├── rpc ├── gnmi │ ├── img │ │ ├── auth-overview.png │ │ ├── gnmi_dialout.png │ │ ├── auth-message-flow.png │ │ ├── grpctunnelclient_embedded.png │ │ ├── tunnelclienttotunnelclient.png │ │ ├── tunnelclienttotunnelserver.png │ │ ├── tunnelservertotunnelclient.png │ │ ├── grpctunnelclient_standalone.png │ │ ├── grpctunnel-client-to-server-detail.png │ │ ├── grpctunnelclient_embed_gnmicollector.png │ │ └── grpctunnelserver_embed_gnmicollector.png │ ├── README.md │ ├── gnmi-extensions.md │ ├── gnmi-history.md │ ├── gnmi-authentication.md │ ├── gnmi-master-arbitration.md │ ├── gnmi-path-strings.md │ ├── gnmi-commit-confirmed.md │ ├── protobuf-vals.md │ ├── gnmi-depth.md │ ├── gnmi-path-conventions.md │ ├── decimal64-deprecation.md │ ├── gnmi-config-subscriptions.md │ └── gnmignoissh-dialout-grpctunnel.md └── gnoi │ └── README.md ├── README.md ├── ietf ├── bin │ ├── build-draft.sh │ └── xml-add-yang.py └── drafts │ ├── routing-policy-example.xml │ ├── draft-openconfig-rtgwg-gnmi-spec-01.xml │ ├── draft-openconfig-rtgwg-local-routing-00.xml │ ├── draft-openconfig-rtgwg-network-instance-01.xml │ ├── draft-openconfig-rtgwg-network-instance-00.xml │ ├── draft-shaikh-idr-bgp-model-00.xml │ └── draft-openconfig-rtgwg-gnmi-spec-01.txt └── LICENSE /rpc/gnmi/img/auth-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/auth-overview.png -------------------------------------------------------------------------------- /rpc/gnmi/img/gnmi_dialout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/gnmi_dialout.png -------------------------------------------------------------------------------- /rpc/gnmi/img/auth-message-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/auth-message-flow.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reference 2 | This repository contains reference implementations / tooling related to 3 | OpenConfig based network management. -------------------------------------------------------------------------------- /rpc/gnmi/img/grpctunnelclient_embedded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/grpctunnelclient_embedded.png -------------------------------------------------------------------------------- /rpc/gnmi/img/tunnelclienttotunnelclient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/tunnelclienttotunnelclient.png -------------------------------------------------------------------------------- /rpc/gnmi/img/tunnelclienttotunnelserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/tunnelclienttotunnelserver.png -------------------------------------------------------------------------------- /rpc/gnmi/img/tunnelservertotunnelclient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/tunnelservertotunnelclient.png -------------------------------------------------------------------------------- /rpc/gnmi/img/grpctunnelclient_standalone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/grpctunnelclient_standalone.png -------------------------------------------------------------------------------- /rpc/gnmi/img/grpctunnel-client-to-server-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/grpctunnel-client-to-server-detail.png -------------------------------------------------------------------------------- /rpc/gnmi/img/grpctunnelclient_embed_gnmicollector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/grpctunnelclient_embed_gnmicollector.png -------------------------------------------------------------------------------- /rpc/gnmi/img/grpctunnelserver_embed_gnmicollector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openconfig/reference/HEAD/rpc/gnmi/img/grpctunnelserver_embed_gnmicollector.png -------------------------------------------------------------------------------- /rpc/gnoi/README.md: -------------------------------------------------------------------------------- 1 | # gNOI - gRPC Network Operations Interface 2 | 3 | gNOI protobufs and code artefacts can be found in 4 | github.com/openconfig/gnoi. 5 | 6 | -------------------------------------------------------------------------------- /ietf/bin/build-draft.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # build the draft given as an argument 4 | 5 | if [ ! -e "$1" ]; then 6 | echo "USAGE: $0 " 7 | echo " outputs .COMPILED.xml in the current directory" 8 | echo " along with the built .txt file. The COMPILED and txt files should" 9 | echo " be submitted to the IETF tool" 10 | exit 1 11 | fi 12 | 13 | BINDIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 14 | TXTFN=`echo $1 | sed 's/xml/txt/g'` 15 | COMPILED=`echo $1 | sed 's/.xml/.COMPILED.xml/g'` 16 | COMPILEDTXT=`echo $COMPILED | sed 's/xml/txt/g'` 17 | 18 | $BINDIR/xml-add-yang.py -i $1 -o $COMPILED && xml2rfc $COMPILED -o /tmp/$TXTFN && mv /tmp/$TXTFN `pwd`/$TXTFN 19 | -------------------------------------------------------------------------------- /rpc/gnmi/README.md: -------------------------------------------------------------------------------- 1 | # gNMI - gRPC Network Management Interface 2 | 3 | This repository contains the specification of the gRPC Network Management 4 | Interface (gNMI). This service defines an interface 5 | for a network management system to interact with a network element. 6 | 7 | The protobuf specification is stored in 8 | [openconfig/gnmi](https://github.com/openconfig/gnmi/tree/master/proto/gnmi). 9 | 10 | The repository contents are as follows: 11 | 12 | 13 | * Specification for gNMI - [gnmi-specification.md](gnmi-specification.md). 14 | * Authentication Specification for gNMI - [gnmi-authentication.md](gnmi-authentication.md) 15 | * Path Conventions for gNMI - [gnmi-path-conventions.md](gnmi-path-conventions.md) 16 | * gNMI Support for Multiple Client Roles and Master Arbitration - [gnmi-master-arbitration.md](gnmi-master-arbitration.md) 17 | * gNMI/gNOI/SSH Dial-out via gRPC Tunnel - [gnmignoissh-dialout-grpctunnel.md](gnmignoissh-dialout-grpctunnel.md) 18 | 19 | **Note:** This is not an official Google product. 20 | 21 | -------------------------------------------------------------------------------- /ietf/drafts/routing-policy-example.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | prefix-set-A 9 | 10 | 192.0.2.0/24 11 | 24..32 12 | 13 | 14 | 10.0.0.0/16 15 | 16..32 16 | 17 | 18 | 192.168.0.0/19 19 | 19..24 20 | 21 | 22 | 23 | 24 | 25 | cust-tag1 26 | 27 | 10 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | export-tagged-BGP 36 | 37 | 38 | term-0 39 | 40 | ns:OSPF3 41 | 42 | cust-tag1 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /ietf/bin/xml-add-yang.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import getopt 4 | import sys 5 | import re 6 | import os 7 | import requests 8 | 9 | def main(): 10 | def usage(): 11 | sys.stderr.write("Usage %s: \n" % sys.argv[0]) 12 | sys.stderr.write(" -h -- this message\n") 13 | sys.stderr.write(" -i -- input file\n") 14 | sys.stderr.write(" -o -- output file path\n") 15 | 16 | output_fn = None 17 | input_fn = None 18 | 19 | yfile_re = re.compile("^([ ]+)?<\?yfile include=\"(?P.*)\"([ ]+)?\?>") 20 | 21 | opts,remaining = getopt.getopt(sys.argv[1:], 'hi:o:', ['help', 'input=', 22 | 'output=']) 23 | 24 | for opt, arg in opts: 25 | if opt in ('-o', '--output'): 26 | output_fn = arg 27 | elif opt in ('-i', '--input'): 28 | input_fn = arg 29 | 30 | if output_fn is None or input_fn is None: 31 | usage() 32 | sys.stderr.write("\n") 33 | sys.stderr.write("FATAL: must specify output filename\n") 34 | sys.exit(1) 35 | 36 | try: 37 | infh = open(input_fn, 'r') 38 | except IOError, m: 39 | sys.stderr.write("FATAL: could not open input filename (%s)" % m) 40 | sys.exit(1) 41 | 42 | if not os.path.isabs(input_fn): 43 | inabsdir = os.path.dirname(os.path.abspath(input_fn)) 44 | else: 45 | inabsdir = os.path.dirname(input_fn) 46 | 47 | try: 48 | outfh = open(output_fn, 'w') 49 | except IOError, m: 50 | sys.stderr.write("FATAL: could not open output filename (%s)" % m) 51 | sys.exit(1) 52 | 53 | for l in infh.readlines(): 54 | if not yfile_re.match(l): 55 | outfh.write(l) 56 | else: 57 | ifn = yfile_re.sub('\g', l).rstrip("\n") 58 | process = False 59 | c = None 60 | if re.match("^http(s)?://", ifn): 61 | r = requests.get(ifn) 62 | c = r.content 63 | elif re.match("^file://", ifn): 64 | ifn = re.sub("^file://", '', ifn) 65 | process = True 66 | elif not os.path.isabs(ifn): 67 | ifn = inabsdir+"/"+ifn 68 | process = True 69 | else: 70 | process = True 71 | 72 | if process: 73 | try: 74 | c = open(ifn, 'r').readlines() 75 | except IOError, m: 76 | sys.stderr.write("FATAL: could not open a referenced file (%s)\n" % m) 77 | sys.exit(1) 78 | 79 | if c is not None: 80 | outfh.write("\n") 81 | for l in c: 82 | outfh.write(l) 83 | outfh.write("\n") 84 | 85 | if __name__ == '__main__': 86 | main() 87 | 88 | 89 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-extensions.md: -------------------------------------------------------------------------------- 1 | # Extensions to gNMI 2 | 3 | **Contributors**: Rob Shakir (robjs@google.com), Carl Lebsack (csl@google.com), 4 | Nick Ethier (nethier@jive.com), Anees Shaikh (aashaikh@google.com) 5 | 6 | **Updated**: January 25th, 2018 7 | 8 | **Version**: 0.1.0 9 | 10 | ## Extending gNMI 11 | 12 | gNMI defines a standard set of RPCs which form the core protocol functionality. 13 | In some implementations additional data is required within RPC payloads that is 14 | not currently within the core protobuf definition. Extensions to gNMI define a 15 | means to add new payload to gNMI RPCs for these use cases without requiring 16 | changes in the core protocol specification. 17 | 18 | An extension that is defined to a gNMI RPC MUST NOT modify the base behaviour of 19 | the RPC. That is to say fields MUST NOT be interpreted in a manner which does 20 | not match the base specification. The success or failure of an RPC MAY be 21 | impacted by the extension. If the base specification's behaviour is to be 22 | modified, an implementation MUST define a new service which specifies the 23 | modified RPCs. A target MAY support both gNMI and such extension services as 24 | different service endpoints on a common gRPC server. 25 | 26 | gNMI extensions are defined to be carried within the `extension` field of each 27 | top-level message of the gNMI RPCs. Extensions can added to both RPC request and 28 | response messages, such that a client and target can both communicate extended 29 | information. gNMI extensions are implemented directly within the request and 30 | response messages to allow logging, debugging, or tracing frameworks to capture 31 | their contents, and avoid the fragility of carrying extension information in 32 | metadata. 33 | 34 | ## The Extension Message 35 | 36 | The `Extension` message is defined within the `gnmi_ext.proto` specification. As 37 | mentioned above, it is carried as a `repeated` field within each of the 38 | top-level request and response gNMI messages. 39 | 40 | ## Well-Known and Registered Extensions 41 | 42 | Well-known extensions are defined directly within the `gnmi_ext.proto` protocol 43 | buffer. A well known extension is defined as one that is expected to be 44 | supported by multiple implementations - for example, to support proxying, or 45 | master arbitration between different writers. 46 | 47 | Registered extensions are those that are more esoteric, or applicable to a 48 | smaller set of use cases. In this case, the definition of the extension is 49 | defined outside of the `gnmi.proto` or `gnmi_ext.proto` files. A registered 50 | extension is given a unique identifier - which must be centrally registered in 51 | the `gnmi_ext.proto` file. Registered extensions SHOULD provide a link to a 52 | specification as to their operation. The gNMI `Extension` message is made 53 | transparent to the definition of the protobuf message which defines the 54 | extension by utilising a `bytes` field, which contains the binary marshalled 55 | protobuf used to carry extension options. 56 | 57 | Registered extensions MAY be promoted to well known extensions in the case that 58 | their adoption becomes widespread. 59 | 60 | ## Extension Message Definition 61 | 62 | The `Extension` message consists of a single `oneof` which may contain: 63 | 64 | * A well-known extension. Each well known extension defined in the 65 | `gnmi_ext.proto` file will be added to the `oneof` and assigned a unique 66 | field tag. 67 | * A registered extension, expressed as a `RegisteredExtension` message. The 68 | subfields of this message are: 69 | * An enumerated `id` field used to store the unique ID assigned to the 70 | registered extension. 71 | * A `bytes` field which stores the binary-marshalled protobuf for the 72 | extension. 73 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-history.md: -------------------------------------------------------------------------------- 1 | # gNMI History Extension 2 | 3 | **Contributors:** Justin Costa-Roberts, Aaron Beitch, Mike Fink 4 | 5 | **Date:** August 4, 2020 6 | 7 | **Version:** 0.1.0 8 | 9 | # 1. Purpose 10 | 11 | In certain applications it is necessary not only to retrieve current data from a 12 | data tree, but also to allow querying historical data. The gNMI History 13 | extension enables clients both to retrieve data at a specific time in the past, 14 | and to request all updates applied to a data tree between two specified times. 15 | 16 | # 2. Definition 17 | 18 | A `History` message is embedded in an Extension message in the 19 | `SubscribeRequest` proto. 20 | 21 | ## 2.1 Proto 22 | 23 | ``` 24 | message TimeRange { 25 | int64 start = 1; 26 | int64 end = 2; 27 | } 28 | 29 | message History { 30 | oneof request { 31 | int64 snapshot_time = 1; 32 | TimeRange range = 2; 33 | } 34 | } 35 | ``` 36 | 37 | ## 2.2 SubscribeRequest handling 38 | 39 | The History extension may be applied only to `ONCE` and `STREAM` subscriptions. 40 | Requests for historical data can be either of two types: a snapshot at a 41 | specified time, or a set of updates between two times. The `History` message's 42 | request field is a `oneof` field whose type indicates which of these request 43 | types applies. 44 | 45 | In all cases, times are represented as int64s interpreted as nanoseconds since 46 | the Unix Epoch. 47 | 48 | ### 2.2.1 Snapshot requests 49 | 50 | If the `snapshot_time` field is set, the request is for a snapshot. The 51 | subscription mode for a snapshot request must be `ONCE`; otherwise the server 52 | must return an `INVALID_ARGUMENT` error. The server must transmit the data 53 | indicated in the `SubscribeRequest` as it existed on the server at the specified 54 | time. If the specified time indicates a future time at the point the server 55 | receives the request, the server may either return an `UNIMPLEMENTED` error or 56 | choose to wait until the specified time has been reached. 57 | 58 | ### 2.2.2 Range requests 59 | 60 | If the `range` field is set, the request is for the set of updates that occurred 61 | during the half-open interval between the specified start and end times. Such a 62 | request may return multiple updates per leaf, so the subscription mode for a 63 | range request must be `STREAM`. If the mode of a range request is not `STREAM`, 64 | the server should return an `INVALID_ARGUMENT` error. For the paths specified in 65 | the `SubscriptionList`, the server must transmit all updates it's aware of that 66 | occurred at the start time or later and before the end time specified in the 67 | `TimeRange`, and then close the RPC. As usual, the server should also transmit 68 | the specified data tree as it existed at the subscription start time unless the 69 | `updates_only` field on the `SubscriptionList` message is set. 70 | 71 | If `TimeRange`'s start time is later than its end time, the server must return 72 | an `INVALID_ARGUMENT` error. If a start or end time has not yet elapsed when the 73 | server receives the request, the server may either return an `UNIMPLEMENTED` 74 | error or honor the request by waiting until the specified time. Clients may 75 | therefore request open-ended `STREAM` subscriptions beginning in the past by 76 | setting the end time to, for example, the largest int64 value. 77 | 78 | ### 2.2.3 Considerations for requests not immediately serviceable 79 | 80 | Clients should not expect servers to service requests with start or end times in 81 | the future. Servers may honor such requests in order to account for the 82 | possibility of moderate differences in local time between the client and server, 83 | but clients should expect that times far into the future will not be serviced, 84 | and that significant clock desynchronization may cause the server to return an 85 | error for requests with specified times near the present. Finally, clients 86 | should expect that in order not to exhaust resources, servers may limit the 87 | number of open requests that cannot immediately be serviced. 88 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-authentication.md: -------------------------------------------------------------------------------- 1 | ## gNMI Authentication and Encryption 2 | 3 | 4 | **Updated**: July 26, 2019 5 | **Version:**: 0.1.1 6 | 7 | #### Background 8 | 9 | Network devices managed by the gRPC Network Management Interface ([gNMI](https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md)) must support secure bidirectional communication over a [gRPC](http://www.grpc.io/) channel, along with standard authorization and accounting of all management operations. An example of the primary entities of a gNMI-based management system is shown in the figure below. The configuration system and telemetry collectors act as RPC clients to the network device (target). The target exposes the gNMI service with methods for subscribing to telemetry streams or sending configuration data. 10 | 11 | ![drawing](img/auth-overview.png) 12 | 13 | #### Requirements on the network device (gNMI target) 14 | 15 | 16 | 17 | * Allow installation of an X.509 PEM certificate and private key to enable server authentication for the TLS connection. 18 | * Verify that certificates are valid on both sides and authenticate either with the gRPC-contained user and password, or the CN in the client certificate. 19 | * Accept username / password credentials for authentication operations. 20 | * Accept username to authorize operations against the device's standard AAA (generally, TACACS) mechanisms. 21 | * Use a single gRPC endpoint service for all operations (with separate RPCs supporting configuration and telemetry operations). Each client (e.g., telemetry collector or configuration system) may open a separate channel with its own authentication credentials. 22 | * Leverage [gRPC authentication](http://www.grpc.io/docs/guides/auth.html) support. 23 | 24 | #### Encryption 25 | 26 | 27 | 28 | * All communication between gRPC client and server must be encrypted by TLS (TLS 1.2). The gRPC channel must be in an encrypted state before it is considered usable. 29 | * If the client and server are unable to negotiate an encrypted channel, the channel establishment should fail with an error. 30 | * Fallback to unencrypted communication is prohibited. 31 | * The network element will perform certificate based validation of the connecting network management system to ensure the endpoint is an authorized entity. 32 | * The target must provide a means for the operator to install a certificate bundle on the network element, and the target must use the supplied bundle to validate incoming connections to the network element. 33 | * The target must support a process to periodically rotate the keyfile/certificate bundle. 34 | 35 | #### Credentials and Authentication 36 | 37 | 38 | 39 | * Configuration operations carried over the encrypted connection will carry credentials (username/password) in the metadata 40 | of each gRPC message. Configuration changes require a user with Read-Write permission. 41 | * The target will use these credentials to authorize the configuration operation using currently available AAA methods on 42 | the network element. 43 | * The network element uses the local AAA configuration to determine where and what type of AAA request to issue. 44 | * For example, on a network element configured to use TACACS for command authorization, a Get(/interfaces) 45 | request for user:password would trigger a TACACS command authorization request using the same username. 46 | * Future versions of the authentication scheme may use a username/password credential carried inside a field of the X.509 47 | certificate, rather than exclusive use of RPC metadata. 48 | 49 | #### Telemetry Authentication 50 | 51 | * Each telemetry message will not be authenticated with a username/password, as this is redundant and will not be a 52 | performant solution. 53 | * Each telemetry message will only be carried over the encrypted gRPC streaming channel which was previously authenticated. 54 | * Telemetry Subscribe() RPCs require a username/password credential inside the metadata. The 55 | Subscribe and Get RPCs do not make configuration changes to a device and thus should be allowed for users with Read-Only or 56 | Read-Write permissions. 57 | 58 | **Contributors**: Alex Bogdanov, Josh George, Carl Lebsack, Chris Morrow, Anees Shaikh, Rob Shakir 59 | 60 | ## Appendix - gRPC Authentication Flow Diagram 61 | 62 | 63 | ![gNMI Authentication Message Flow](img/auth-message-flow.png) 64 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-master-arbitration.md: -------------------------------------------------------------------------------- 1 | # gNMI Support for Multiple Client Roles and Master Arbitration 2 | 3 | **Contributors:** Xinming Chen, Rob Shakir, Waqar Mohsin, Anees Shaikh, Tomek 4 | Madejski, Alireza Ghaffarkhah 5 | 6 | **Date:** April 20th, 2018 7 | 8 | **Version:** 0.1.0 9 | 10 | # 1 Master Arbitration 11 | 12 | For high availability, a system may run multiple replicas of a gNMI client. 13 | Among the replicas, only one client should be elected as master and do gNMI 14 | operations that mutate any state on the target. However, in the event of a 15 | network partition, there can be two or more replicas thinking themselves as 16 | master. For read-only RPCs, this is OK. But if they both call the `Set` RPC, the 17 | target may be incorrectly configured by the stale master. Therefore, "master 18 | arbitration" is needed when multiple clients exist. 19 | 20 | Master arbitration means when a gNMI client connects, it provides a 128-bit 21 | integer `election_id`. The election ID MUST be guaranteed to be monotonically 22 | increasing -- a new master's election ID MUST always be larger than its 23 | predecessor. The process through which election IDs are allocated to client 24 | replicas is out-of-scope of this specification. 25 | 26 | The client carries the election ID in all of its `Set` requests. When the target 27 | receives any `Set` request, it looks at the election ID carried with the 28 | requests and stores the largest ID it sees. An election ID that is equal to or 29 | greater than the currently stored one should be accepted as the master. On the 30 | other hand, `Set` requests with no election ID or with a smaller election ID are 31 | rejected and return an error. 32 | 33 | # 2 Client Role 34 | 35 | Sometimes, there is a need to partition the config tree among multiple clients 36 | (where each client in turn could be replicated). This is accomplished by 37 | assigning a *role* to each client. Master arbitration is performed on a per-role 38 | basis. There can be one master for each role, i.e. multiple master clients are 39 | allowed only if they belong to different roles. 40 | 41 | The role is identified by its `id`, which is assigned offline in agreement 42 | across the entire control plane. The target will use the role ID to arbitrate 43 | such that each role has one and only one master controller instance. 44 | 45 | ## 2.1 Default Role 46 | 47 | To simplify for use-cases where multiple roles are not needed, the client can 48 | leave the role message unset in MasterArbitration. This implies default role. 49 | All `Set` RPCs that uses a default role are arbitrated in the same group. 50 | 51 | 52 | # 3 Implementation Detail 53 | 54 | ## 3.1 Proto Definition 55 | 56 | A `MasterArbitration` message is embedded in the gNMI Extension message of the 57 | `SetRequest` proto. It carries the election ID and the role. The message is 58 | defined as following: 59 | 60 | ``` 61 | message MasterArbitration { 62 | Role role = 1; 63 | Uint128 election_id = 2; 64 | } 65 | 66 | message Uint128 { 67 | uint64 high = 1; 68 | uint64 low = 2; 69 | } 70 | 71 | message Role { 72 | string id = 1; 73 | } 74 | ``` 75 | 76 | More fields can be added to the `Role` proto if needed, for example, to specify 77 | what paths the role can read/write. 78 | 79 | ## 3.2 `SetRequest` Handling 80 | 81 | In order to update the election ID as soon as a new master is elected, the 82 | client is required to send an empty `Set` RPC (with the election ID only) as 83 | soon as it becomes master. The client also carries the election ID in all 84 | subsequent `Set` requests. 85 | 86 | When the target receives a `Set` request, it compares the election ID with the 87 | locally stored one within the same role: 88 | 89 | - If the election ID equals the currently stored one, proceeds with the Set 90 | operation. 91 | 92 | - If the election ID is larger than the currently stored one, updates the 93 | currently stored election ID with the larger one, then proceeds with the Set 94 | operation. 95 | 96 | - If the election ID is smaller than the currently stored one, returns 97 | `PERMISSION_DENIED` error. For debugging purposes, it is recommended that 98 | the target includes the currently stored highest election ID in the error 99 | message string. 100 | 101 | - If the arbitration extension exists but `election_id` is not set, returns 102 | `INVALID_ARGUMENT` error. 103 | 104 | - If there is no arbitration extension associated with the Set request, the 105 | Set request should be accepted and processed. Therefore, client that expects 106 | to ever be part of a replica-group MUST always set this extension, and the 107 | role MUST be populated. 108 | 109 | - If `role` message is not set, this request is considered as using the 110 | default role. It will be arbitrated against all the clients that have the 111 | default role. 112 | 113 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-path-strings.md: -------------------------------------------------------------------------------- 1 | ## Representing gNMI Paths as Strings 2 | 3 | **Authors**: 4 | robjs, aashaikh, csl, hines. 5 | @google.com 6 | 7 | October 2018 8 | 9 | 10 | ## Overview 11 | 12 | This document provides a specification for the representation of a gNMI 13 | [`Path`](https://github.com/openconfig/gnmi/blob/master/proto/gnmi/gnmi.proto#L133) 14 | message as a string. String encoding MUST NOT be used within the protocol, but 15 | provides means to simplify human interaction with gNMI paths - for example, in 16 | device or daemon configuration. 17 | 18 | 19 | ## String Representation of a Single Element 20 | 21 | A gNMI path consists of a series of `PathElem` messages. These messages 22 | consist of a `name` and a map of `keys`. Each `PathElem` is represented as a 23 | string in the form: 24 | 25 | ``` 26 | name[key1=val1][key2=val2] 27 | ``` 28 | 29 | Where `name` is the `PathElem` `name` field, `key1` represents a key of the 30 | `keys` map, and `val1` represents the value corresponding to `key1` within the 31 | map. Where multiple keys are present (as shown with `key1` and `key2`) the 32 | values are encoded in the form: 33 | 34 | ``` 35 | [key=value] 36 | ``` 37 | 38 | and appended to the string. If the key value contains a `]` character, it is 39 | escaped by preceding it with the backslash (`\`) character. Only `]` and `\` 40 | characters must be escaped. Newlines and carriage returns are encoded as `\n` 41 | and `\r` respectively. Unicode characters are encoded as `\u1234` or `\U1234`. 42 | 43 | If multiple keys exist for a particular element, they MUST be specified sorted 44 | alphabetically by the key name. 45 | 46 | 47 | ## String Representation of an Entire Path 48 | 49 | Using the format for each `PathElem` described above, the entire path is formed 50 | by concatenating the series of strings with a `/` character between each 51 | `PathElem`. If the path is absolute (i.e., starts at the schema root), it is 52 | preceded by a `/` character. The `prefix + path` expressed in gNMI is always 53 | absolute. 54 | 55 | 56 | ## Stringified Path Examples 57 | 58 | 59 | 60 | 62 | 64 | 65 | 66 | 81 | 83 | 84 | 85 | 102 | 104 | 105 | 106 | 127 | 129 | 130 | 131 | 159 | 161 | 162 | 163 | 174 | 176 | 177 | 178 | 189 | 191 | 192 | 193 | 204 | 206 | 207 |
Path 61 | String Encoding 63 |
67 |
  prefix: <
 68 |         elem: <
 69 |                 name: "a"
 70 |         >
 71 |   >
 72 |   path: <
 73 |         elem: <
 74 |                 name: "b"
 75 |         >
 76 |         elem: <
 77 |                 name: "c"
 78 |         >
 79 |   >
80 |
/a/b/c 82 |
86 |
<
 87 |           elem: <
 88 |                   name: "interfaces"
 89 |           >
 90 |             elem: <
 91 |                   name: "interface"
 92 |                   key: <
 93 |                           key: "name"
 94 |                           value: "Ethernet1/2/3"
 95 |                   >
 96 |           >
 97 |           elem: <
 98 |                   name: "state"
 99 |           >
100 | >
101 |
/interfaces/interface[name=Ethernet/1/2/3]/state 103 |
107 |
<
108 |                 elem: <
109 |                         name: "interfaces"
110 |                 >
111 |                 elem: <
112 |                         name: "interface"
113 |                         key: <
114 |                                 key: "name"
115 |                                 value: "Ethernet1/2/3"
116 |                         >
117 |                 >
118 |                 elem: <
119 |                         name: "state"
120 |                 >
121 |                 elem: <
122 |                         name: "counters"
123 |                 >
124 |         >
125 | >
126 |
/interfaces/interface[name=Ethernet/1/2/3]/state/counters 128 |
132 |
<
133 |         elem: <
134 |                 name: "network-instances"
135 |         >
136 |         elem: <
137 |                 name: "network-instance"
138 |                 key: <
139 |                         key: "name"
140 |                         value: "DEFAULT"
141 |                 >
142 |         >
143 |         elem: <
144 |                 name: "protocols"
145 |         >
146 |         elem: <
147 |                 name: "protocol"
148 |                 key: <
149 |                         key: "identifier"
150 |                         value: "ISIS"
151 |                 >
152 |                 key: <
153 |                         key: "name"
154 |                         value: "65497"
155 |                 >
156 |         >
157 | >
158 |
/network-instances/network-instance[name=DEFAULT]/protocols/protocol[identifier=ISIS][name=65497] 160 |
164 |
<
165 |         elem: <
166 |                 name: "foo"
167 |                 key: <
168 |                         key: "name"
169 |                         value: "]"
170 |                 >
171 |         >
172 | >
173 |
/foo[name=\]] 175 |
179 |
<
180 |         elem: <
181 |                 name: "foo"
182 |                 key: <
183 |                         key: "name"
184 |                         value: "["
185 |                 >
186 |         >
187 | >
188 |
/foo[name=[] 190 |
194 |
<
195 |         elem: <
196 |                 name: "foo"
197 |                 key: <
198 |                         key: "name"
199 |                         value: "[\]"
200 |                 >
201 |         >
202 | >
203 |
/foo[name=[\\\]] 205 |
208 | 209 | 210 | A reference implementation of path to string encoding, and string to path can 211 | be found in ygot's 212 | [pathstrings.go](https://github.com/openconfig/ygot/blob/master/ygot/pathstrings.go). 213 | 214 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-commit-confirmed.md: -------------------------------------------------------------------------------- 1 | # gNMI Commit Confirmed Extension 2 | 3 | **Contributors:** Gautham V Kidiyoor, Roman Dodin, Rob Shakir, Vinit Kanvinde, Priyadeep Bangalore Lokesh 4 | 5 | **Date:** September 20, 2023 6 | 7 | **Version:** 0.1.0 8 | 9 | # 1. Purpose 10 | 11 | In certain deployments, client and server is separated by a complex network, 12 | hence we cannot assume 13 | 14 | - The pushed configuration will not break connectivity to the network device. 15 | - The network device have out-of-band access. 16 | 17 | This feature provides a way to auto rollback the applied configuration after a 18 | certain duration if a bad configuration was pushed. 19 | 20 | # 2. Summary 21 | 22 | The proposed proto has a subset of confirmed commit functionality as defined in 23 | NETCONF protocol([RFC6241](https://datatracker.ietf.org/doc/html/rfc6241#section-8.4)). The proposal has a healthy disregard to few functionality 24 | defined in the RFC with the intention that most of the gRPC API clients are going to 25 | be automated systems and the proto should facilitate a simpler implementation of 26 | client workflows and server implementation. 27 | 28 | The server can be viewed as a singleton resource, at any given point in time there 29 | can be only one commit active. This commit can be either confirmed or canceled 30 | before a new commit can begin. Client is expected to provide full configuration 31 | during the commit request, the commit cannot be amended once issued. 32 | 33 | # 3. Definition 34 | 35 | A `Commit` message is embedded the Extension message of the SetRequest proto. 36 | 37 | ## 3.1 Proto 38 | 39 | ```proto 40 | // Commit confirmed extension allows automated revert of the configuration after 41 | // certain duration if an explicit confirmation is not issued. It allows explicit 42 | // cancellation of the commit during the rollback window. There cannot be more 43 | // than one commit active at a given time. 44 | // The document about gNMI commit confirmed can be found at 45 | // https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-commit-confirmed.md 46 | message Commit { 47 | // ID is provided by the client during the commit request. During confirm and cancel 48 | // actions the provided ID should match the ID provided during commit. 49 | // If ID is not passed in any actions server shall return error. 50 | // Required. 51 | string id = 1; 52 | oneof action { 53 | // commit action creates a new commit. If a commit is on-going, server returns error. 54 | CommitRequest commit = 2; 55 | // confirm action will confirm an on-going commit, the ID provided during confirm 56 | // should match the on-going commit ID. 57 | CommitConfirm confirm = 3; 58 | // cancel action will cancel an on-going commit, the ID provided during cancel 59 | // should match the on-going commit ID. 60 | CommitCancel cancel = 4; 61 | // set rollback duration action sets the rollback duration of an on-going commit 62 | // to a new value. 63 | // The ID provided with the Commit message should match the on-going commit ID. 64 | CommitSetRollbackDuration set_rollback_duration = 5; 65 | } 66 | } 67 | 68 | // CommitRequest is used to create a new confirmed commit. It hold additional 69 | // parameter requried for commit action. 70 | message CommitRequest { 71 | // Maximum duration to wait for a confirmaton before reverting the commit. 72 | google.protobuf.Duration rollback_duration = 1; 73 | } 74 | 75 | // CommitConfirm is used to confirm an on-going commit. It hold additional 76 | // parameter requried for confirm action. 77 | message CommitConfirm {} 78 | 79 | // CommitCancel is used to cancel an on-going commit. It hold additional 80 | // parameter requried for cancel action. 81 | message CommitCancel {} 82 | 83 | // CommitSetRollbackDuration is used to set the existing rollback duration value 84 | // of an on-going commit to a new desired value. 85 | message CommitSetRollbackDuration { 86 | // Maximum duration to wait for a confirmaton before reverting the commit. 87 | google.protobuf.Duration rollback_duration = 1; 88 | } 89 | ``` 90 | 91 | ## 3.2 SetRequest handling 92 | 93 | ### 3.2.1 Commit 94 | 95 | A commit can be initiated by providing `CommitRequest` as action in the extension. A `id` must to be 96 | provided by the client. The server shall associate the commit with the provided `id`. 97 | During confirm or cancel action the provided `id` must match the `id` of the on-going commit. 98 | 99 | `rollback_duration` can be used to override the default rollback duration. In JSON format, the Duration 100 | type is encoded as a string rather than an object where the string ends in the suffix "s" (indicating 101 | seconds) Eg. "10s". object Server should maintain a default 10 minutes duration when `rollback_duration` 102 | is not present in the request. If a confirmation call is not received before the rollback duration then 103 | the configuration is reverted. 104 | 105 | If a `CommitRequest` is issued whilst an existing rollback counter is running then the server returns with 106 | FAILED_PRECONDITION error. 107 | 108 | If a SetRequest call is made without extension whilst an existing rollback counter is running then a 109 | FAILED PRECONDITION error is returned. 110 | 111 | ### 3.2.2 Confirm 112 | 113 | Confirmation can be issued by providing `ConfirmRequest` as action in the extension. The value of `id` 114 | should be equivalent to the `id` of the on-going commit. 115 | 116 | If the server is not waiting for confirmation or if the value doesn’t match the on-going commit then 117 | FAILED_PRECONDITION or INVALID_ARGUMENT error is returned respectively. 118 | 119 | ### 3.2.3 Cancel 120 | 121 | Cancellation can be issued by providing `CancelRequest` as action in the extension. The value of `id` 122 | should be equivalent to the id of the on-going commit. 123 | 124 | If the server is not waiting for cancellation or if the value doesn’t match the on-going commit 125 | then FAILED_PRECONDITION or INVALID_ARGUMENT error is returned respectively. 126 | 127 | ### 3.2.4 Set Rollback Duration 128 | 129 | When a commit is on-going, the existing rollback duration can be reset to a new value 130 | by providing `SetRollbackDurationRequest` as action in the extension. The value of `id` should 131 | be equivalent to the id of the on-going commit. 132 | 133 | Note, that the rollback duration value provided in the `SetRollbackDurationRequest` action 134 | will effectively overwrite the existing rollback duration timer. It will not append to the 135 | existing rollback duration time but set it to the new value provided. 136 | 137 | The value of `rollback_duration` should be provided and be greater than 0. If the value is 0 or not 138 | provided then INVALID_ARGUMENT error is returned. 139 | 140 | If the server doesn't have an on-going commit with confirmation or if the value doesn’t match the on-going commit then 141 | FAILED_PRECONDITION or INVALID_ARGUMENT error is returned respectively. 142 | -------------------------------------------------------------------------------- /rpc/gnmi/protobuf-vals.md: -------------------------------------------------------------------------------- 1 | # Carrying Binary Wire Format Protobuf Messages in gNMI 2 | **Contributors**: robjs, csl 3 | May 2018 4 | *Implementation Status*: Proposal 5 | 6 | ## Problem Statement 7 | For some applications, the data carried by gNMI is directly described by a 8 | Protobuf IDL file which has been auto-generated from a YANG schema. Elements 9 | within the Protobuf IDL are therefore 1:1 mapped to those within the YANG 10 | schema - with the mapping between the YANG tree node and the protobuf 11 | entity being established by the schema path of each. 12 | 13 | When carrying such protobufs on the wire, it is undesirable to encode the 14 | message name and namespace into a `protobuf.Any` field, as this: 15 | 16 | * Causes duplication of data on the wire - since the gNMI Notification's path 17 | (the concatenated `path` and `prefix` fields) already indicates which message 18 | is serialised within the Notification. 19 | 20 | * Results in incompatibilities when generated protobufs are within different 21 | namespaces, but represent the same YANG schema. This is typically the case 22 | when generating an augmented version of a standard schema. In this case, the 23 | augmented messages are backwards compatible with the standard messages, since 24 | they are a strict superset of the fields, and hence can be deserialised into 25 | the "standard" message. The differing type in `protobuf.Any` does not allow 26 | such deserialisation in standard library implementations. 27 | 28 | This document describes how binary encoded protobufs are carried within gNMI, 29 | and a mechanism for a schema-unaware client to retrieve the mapping of YANG path 30 | to protobuf message name. This latter ability is of use where a schema-unaware 31 | collector wishes at run-time to render paths to strings. 32 | 33 | ## Implementation 34 | 35 | ### Encoding in `TypedValue` 36 | 37 | A new field is included within the `TypedValue` message's `value` `oneof` named 38 | `protobuf_bytes`. When a target or client populates this field it indicates 39 | that the content is a binary-marshalled Protobuf message. The protobuf 40 | message's type is determined by the tuple of ``. 42 | 43 | The contents of the field must be a byte array encoded according to the 44 | [Protobuf Encoding 45 | guide](https://developers.google.com/protocol-buffers/docs/encoding). 46 | 47 | ### Retrieving the Protobuf IDL 48 | 49 | The target exposes a new origin `gnmi.schemas`, which is used to store schema 50 | information relating to encoding in gNMI. This origin is used to store any YANG 51 | model with an `openconfig-extension:origin` extension statement set to 52 | `gnmi.schemas`. 53 | 54 | The following YANG schema should be exposed under this origin. 55 | 56 | ``` 57 | module gnmi-protobuf-encoding { 58 | // Skip preamble 59 | 60 | container protobuf-typemap { 61 | list origin { 62 | key "name"; 63 | 64 | leaf name { 65 | type string; 66 | description 67 | "The name of a origin for which protobuf 68 | message encoding is supported."; 69 | } 70 | 71 | list container { 72 | key "path"; 73 | 74 | description 75 | "A list of containers within the YANG 76 | schema that has an associated protobuf 77 | message. The container is uniquely 78 | identified by its YANG schema path."; 79 | 80 | leaf path { 81 | type string; 82 | description 83 | "A YANG schema path - represented as 84 | each element separated by / characters. 85 | YANG schema paths MUST never contain 86 | keys."; 87 | } 88 | 89 | leaf message-name { 90 | type string; 91 | description 92 | "A Protobuf message name. This name 93 | should use the fully resolved path 94 | to the protobuf message."; 95 | } 96 | 97 | leaf augmented-message-name { 98 | type string; 99 | description 100 | "A Protobuf message name corresponding 101 | to the fully resolved path to a protobuf 102 | message that also includes augmentations 103 | made by the implementation."; 104 | } 105 | } 106 | } 107 | } 108 | } 109 | ``` 110 | 111 | Within this data: 112 | 113 | * The YANG schema path in the `path` leaf MUST represent the absolute schema 114 | tree ID to a particular container or list element within the YANG schema as 115 | defined by [RFC6020 Section 116 | 6.5](https://tools.ietf.org/html/rfc6020#section-6.5). The schema path MUST 117 | NOT be a path to a leaf element. 118 | * The `message-name` leaf MUST represent a 119 | fully resolved Protobuf message name, in the form `source.tld/package.message` 120 | including any required hierarchy as described by the `type_url` field of 121 | [any.proto](https://github.com/google/protobuf/blob/master/src/google/protobuf/any.proto#L123-L149). 122 | The message name corresponds to the Protobuf message name used for that path, 123 | for example `proto.openconfig.net/openconfig.Interfaces`. 124 | * The augmented message name is optionally populated by a device that also 125 | supports a protobuf message which contains additional fields added by local 126 | YANG modules which `augment` the base schema. This message MUST be backwards 127 | compatible with the message in specified in `message-name`. This message can 128 | be used by a client which wishes to unmarshal all fields in the message sent 129 | by the device. 130 | 131 | 132 | 133 | When a client issues a `Get` or `Subscribe` RPC to retrieve information from 134 | the `gnmi.schemas` origin, the response MUST indicate the supported 135 | encodings. 136 | 137 | 138 | ## Examples 139 | 140 | #### Simple Mapping to Protobuf Schema 141 | 142 | Assume that a target supports a module defining `/interfaces/interface/config`, 143 | and its corresponding Protobuf encoding is the `Interfaces.Interface.Config` 144 | message within an `proto.openconfig.net` package named `openconfig`. The target 145 | should respond to a `GetRequest` specifying the `gnmi.schemas` origin with 146 | the following content (shown in JSON encoding): 147 | 148 | ``` 149 | notification: < 150 | timestamp: 1257894000000000000 151 | update: < 152 | path: < 153 | origin: "gnmi.schemas" 154 | > 155 | val: < 156 | json_val: ` 157 | { 158 | "protobuf-typemap": { 159 | "origin": [ 160 | { 161 | "name": "openconfig", 162 | "container": [ 163 | { 164 | "path": "/interfaces/interface/config", 165 | "message-name": "proto.openconfig.net/openconfig.Interfaces.Interface.Config" 166 | } 167 | ] 168 | } 169 | ] 170 | } 171 | } 172 | ` 173 | > 174 | > 175 | > 176 | ``` 177 | 178 | #### Mapping to a Standard and Augmented Schema 179 | 180 | Suppose a target supports a standard YANG schema defining a schema path of 181 | `/system`, along with a non-standard augmentation that adds a new set of nodes 182 | to the `/system` container. In this case, the target should respond to a 183 | `GetRequest` specifying the `gnmi.schemas` origin wtih the following content 184 | (again, shown in JSON encoding): 185 | 186 | ``` 187 | notification: < 188 | timestamp: 1257894000000000000 189 | update: < 190 | path: < 191 | origin: "gnmi.schemas" 192 | > 193 | val: < 194 | json_val: ` 195 | { 196 | "protobuf-typemap": { 197 | "origin": [ 198 | { 199 | "name": "openconfig", 200 | "container": [ 201 | { 202 | "path": "/system", 203 | "message-name": "proto.openconfig.net/openconfig.System" 204 | "augmented-message-name": "proto.vendorx.net/openconfig.System" 205 | } 206 | ] 207 | } 208 | ] 209 | } 210 | } 211 | ` 212 | > 213 | > 214 | > 215 | ``` 216 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-depth.md: -------------------------------------------------------------------------------- 1 | # gNMI Depth Extension 2 | 3 | **Contributors:** Roman Dodin, Matthew MacDonald 4 | 5 | **Date:** March 9, 2024 6 | 7 | **Version:** 0.1.0 8 | 9 | ## 1. Purpose 10 | 11 | The implicit recursive data fetching used by the gNMI servers makes the 12 | implementations simple. Whilst the implementation simplicity is important, the 13 | lack of server-side filtering for the data requested in gNMI RPCs may be 14 | considered a limitation for some gNMI users and systems. 15 | 16 | The gNMI Depth Extension allows a client to control the depth of the recursion 17 | when the server evaluates a group of paths in the `Subscribe` or `Get` RPC. 18 | 19 | Orchestration, Network Management and Monitoring Systems can benefit from this 20 | extension as it: 21 | 22 | 1. reduces the load on the server when data is to be fetched from the Network 23 | OS during the recursive data extraction 24 | 2. reduces the bytes on the wire payload, by sending fewer data 25 | 26 | gNMI Depth Extension proto specification is defined in 27 | [gnmi_ext.proto]( 28 | nmi_ext.proto). 29 | 30 | ## 2. Demo model 31 | 32 | To explain the concept of the depth-based filtering, consider the following 33 | model that is used in the implementation examples throughout this document: 34 | 35 | ```yang 36 | container basket { 37 | leaf name { 38 | type string; 39 | } 40 | 41 | leaf-list contents { 42 | type string; 43 | } 44 | 45 | list fruits { 46 | key "name"; 47 | 48 | leaf name { 49 | type string; 50 | } 51 | 52 | leaf-list colors { 53 | type string; 54 | } 55 | 56 | leaf size { 57 | type string; 58 | } 59 | 60 | container origin { 61 | leaf country { 62 | type string; 63 | } 64 | 65 | leaf city { 66 | type string; 67 | } 68 | } 69 | } 70 | 71 | container description { 72 | leaf fabric { 73 | type string; 74 | } 75 | 76 | } 77 | container broken { 78 | presence "This container is broken"; 79 | leaf reason { 80 | type string; 81 | } 82 | } 83 | } 84 | ``` 85 | 86 | It's tree representation: 87 | 88 | ``` 89 | module: app 90 | +--rw basket 91 | +--rw name? string 92 | +--rw contents* string 93 | +--rw fruits* [name] 94 | | +--rw name string 95 | | +--rw colors* string 96 | | +--rw size? string 97 | | +--rw origin 98 | | +--rw country? string 99 | | +--rw city? string 100 | +--rw description 101 | | +--rw fabric? string 102 | +--rw broken! 103 | +--rw reason? string 104 | ``` 105 | 106 | We populate this data schema with the following values: 107 | 108 | ``` 109 | basket { 110 | contents [ 111 | fruits 112 | vegetables 113 | ] 114 | fruits apples { 115 | size XL 116 | colors [ 117 | red 118 | yellow 119 | ] 120 | origin { 121 | country NL 122 | city Amsterdam 123 | } 124 | } 125 | fruits orange { 126 | size M 127 | } 128 | description { 129 | fabric cotton 130 | } 131 | broken { 132 | reason "too heavy" 133 | } 134 | } 135 | ``` 136 | 137 | ## 3. Concepts 138 | 139 | The Depth extension allows clients to specify the depth of the subtree to be 140 | returned in the response. The depth is specified as the number of levels below 141 | the specified path. 142 | 143 | The extension itself has a single field that controls the depth level: 144 | 145 | ```proto 146 | message Depth { 147 | uint32 level = 1; 148 | } 149 | ``` 150 | 151 | ### 3.1 Depth level values 152 | 153 | #### 3.1.1 Value 0 154 | 155 | Depth value of 0 means no depth limit and behaves the same as if the extension 156 | was not specified at all. 157 | 158 | #### 3.1.2 Value 1 159 | 160 | Value of 1 means only the specified path and its direct children will be 161 | returned. See Children section for more info. 162 | 163 | #### 3.1.2 Value of N 164 | 165 | Value of N where N>1 means all elements of the specified path up to N level and 166 | direct children of N-th level. 167 | 168 | ### 3.2 Children nodes 169 | 170 | The Depth extension operates the value of "direct children of a schema node". 171 | When YANG data modelling language is used, the following elements are 172 | considered as children nodes of a schema node: 173 | 174 | 1. leafs 175 | 2. leaf-lists 176 | 177 | In a generic data model language, the children nodes are the elements of scalar 178 | type, and arrays of these elements, that are direct descendants of the schema 179 | node. 180 | 181 | Only these elements are to be returned if depth extension with non-0 value is 182 | specified for a specified depth level. 183 | 184 | ### 3.3 RPC support 185 | 186 | The Depth extension applies to Get and Subscribe requests only. When used with 187 | Capability and Set RPC the server should return an error. 188 | 189 | ## 4 Examples 190 | 191 | Using the data model from Section 2 we will run through a set of examples using 192 | the patched version of [openconfig/gnmic](https://gnmic.openconfig.net/) client 193 | with the added Depth extension support. 194 | 195 | ### 4.1 depth 1, path `/basket` 196 | 197 | The most common way to use the depth extension (as we see it) is to use it with 198 | level=1. This gets you the immediate child nodes of the schema node targeted by 199 | a path. 200 | 201 | Consider the following gnmic command targeting `/basket` path: 202 | 203 | ```bash 204 | gnmic -e json_ietf get --path /basket --depth 1 205 | ``` 206 | 207 | ```json 208 | [ 209 | { 210 | "contents": [ 211 | "fruits", 212 | "vegetables" 213 | ] 214 | } 215 | ] 216 | ``` 217 | 218 | As per the design, only the leaf and leaf-list nodes are returned. Since our 219 | `/basket` container has only `leaf-list` elements (no leafs) a single element 220 | `contents` is returned. 221 | 222 | You can see how this makes it possible to reduce the amount of data extracted 223 | by the server and sent over the wire. Many applications might require fetching 224 | only leaf values of a certain container to make some informed decision without 225 | requiring any of the nested data. 226 | 227 | ### 4.2 depth 1, path `/basket/fruits` 228 | 229 | When the path targets the list schema node, all elements of this list is 230 | returned with their children nodes 231 | 232 | ```bash 233 | gnmic -e json_ietf get --path /basket/fruits --depth 1 234 | ``` 235 | 236 | ```json 237 | [ 238 | { 239 | "fruits": [ 240 | { 241 | "colors": [ 242 | "red", 243 | "yellow" 244 | ], 245 | "name": "apples", 246 | "size": "XL" 247 | }, 248 | { 249 | "name": "orange", 250 | "size": "M" 251 | } 252 | ] 253 | } 254 | ] 255 | ``` 256 | 257 | Again, please keep in mind that only leafs and leaf-lists are returned for 258 | every list element. 259 | 260 | ### 4.3 depth 2, path `/basket` 261 | 262 | When the depth level is set to values >1, all elements from the path to the 263 | provided level value are returned in full with the last level including only 264 | leafs and leaf-lists. 265 | 266 | ```bash 267 | gnmic -e json_ietf get --path /basket --depth 2 268 | ``` 269 | 270 | ```json 271 | [ 272 | { 273 | "broken": { 274 | "reason": "too heavy" 275 | }, 276 | "contents": [ 277 | "fruits", 278 | "vegetables" 279 | ], 280 | "description": { 281 | "fabric": "cotton" 282 | }, 283 | "fruits": [ 284 | { 285 | "colors": [ 286 | "red", 287 | "yellow" 288 | ], 289 | "name": "apples", 290 | "size": "XL" 291 | }, 292 | { 293 | "name": "orange", 294 | "size": "M" 295 | } 296 | ] 297 | } 298 | ] 299 | ``` 300 | 301 | Here is what happens: 302 | 303 | image 305 | 306 | The 1st level elements are returned, since depth level is 2. 307 | On the 2nd level we return only leafs and leaf-lists, hence the 308 | `.fruits.origin` is not present. 309 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-path-conventions.md: -------------------------------------------------------------------------------- 1 | ## Schema path encoding conventions for gNMI 2 | 3 | **Updated**: June 21, 2017 4 | 5 | **Version**: 0.4.0 6 | 7 | This document is a supplement to the [gNMI specification](https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md), and provides additional guidelines and examples for path encoding. 8 | 9 | ### Path encoding 10 | 11 | Data model path encoding and decoding is required in a gNMI-compliant 12 | management stack. For streaming telemetry, devices (targets) generate 13 | notifications, or updates, with an associated path and value. The 14 | data collector must interpret these paths efficiently. For device 15 | configuration, the NMS client generates configuration data with an 16 | associated path, and passes the data to the target, which must 17 | correctly interpret the path against the appropriate data tree and 18 | apply the configuration. 19 | 20 | ### Guidance for implementors 21 | 22 | Path encoding in gNMI uses a structured path format. This format consists 23 | of a set of elements which consist of a name, and an option map of keys. 24 | Keys are represented as string values, regardless of their type within the 25 | schema that describes the data. Some of the examples below assume YANG- 26 | modeled data since it is a common use case for gNMI, but gNMI has 27 | applicability to any data modeling where the data can be described in a 28 | tree structure with hierarchical paths. 29 | 30 | #### Constructing paths 31 | 32 | gNMI paths are encoded as an ordered list (slice, array, etc.) of `gnmi.PathElem` messages (represented as a repeated field within the protocol buffer definition). Each `PathElem` consists of a name, encoded as a string. An element's name MUST be encoded as a UTF-8 string. Each `PathElem` may optionally specify a set of keys, specified as a `map` (dictionary, or map). The key of the `key` map is the name of a key for the element, and the `value` represent the string-encoded value of the key. Both the key and value of the map MUST contain UTF-8 encoded strings. 33 | 34 | * the root path `/` is encoded as a zero length array (slice) of `PathElem` messages. Example declarations in several languages: 35 | 36 | * Go: `path := []*PathElem{}` 37 | * Python: `path = []` 38 | * C++ : `vector path {};` 39 | 40 | Note this is not the same as a path consisting of a single empty 41 | string element. 42 | 43 | * a human-readable path can be formed by concatenating elements of the prefix 44 | and path using a `/` separator, and preceded by a leading `/` character. 45 | For example: 46 | 47 | ``` 48 | prefix: < 49 | elem: < 50 | name: "a" 51 | > 52 | > 53 | path: < 54 | elem: < 55 | name: "b" 56 | > 57 | elem: < 58 | name: "c" 59 | > 60 | > 61 | ``` 62 | results in the path `/a/b/c` in human readable form. 63 | 64 | * subscription and data retrieval paths (Subscribe and Get RPCs) are 65 | recursive, i.e., select the specified element and all of its descendents. For example, the path: 66 | 67 | ``` 68 | < 69 | elem: < 70 | name: "interfaces" 71 | > 72 | elem: < 73 | name: "interface" 74 | key: < 75 | key: "name" 76 | value: "Ethernet1/2/3" 77 | > 78 | > 79 | elem: < 80 | name: "state" 81 | > 82 | > 83 | ``` 84 | 85 | represents all of the leaves 86 | in the state container, as well as leaves in descendent containers, 87 | e.g., including: 88 | 89 | ``` 90 | /interfaces/interface[name=Ethernet1/2/3]/state/counters 91 | ``` 92 | 93 | * Each string within the `PathElem` message (i.e., the `name`, and the key and value of the `key` map) must contain a valid UTF-8 encoded string. 94 | 95 | #### Paths referencing list elements 96 | 97 | * To reference a list element, both the `name` of the list and `key` map must be specified. i.e., 98 | 99 | ``` 100 | < 101 | elem: < 102 | name: "interfaces" 103 | > 104 | elem: < 105 | name: "interface" 106 | key: < 107 | key: "name" 108 | value: "Ethernet1/2/3" 109 | > 110 | > 111 | elem: < 112 | name: "state" 113 | > 114 | elem: < 115 | name: "counters" 116 | > 117 | > 118 | ``` 119 | 120 | selects the entry in the `interface` list with the `name` key specified to be `Ethernet1/2/3`. 121 | 122 | * Where a list has multiple keys, each key is specified by an additional entry within the `key` map. For example: 123 | 124 | ``` 125 | < 126 | elem: < 127 | name: "network-instances" 128 | > 129 | elem: < 130 | name: "network-instance" 131 | key: < 132 | key: "name" 133 | value: "DEFAULT" 134 | > 135 | > 136 | elem: < 137 | name: "protocols" 138 | > 139 | elem: < 140 | name: "protocol" 141 | key: < 142 | key: "identifier" 143 | value: "ISIS" 144 | > 145 | key: < 146 | key: "name" 147 | value: "65497" 148 | > 149 | > 150 | > 151 | ``` 152 | 153 | * To match all entries within a particular list, the key(s) to the list may be omitted, for example to match the `oper-status` value of all interfaces on a device: 154 | 155 | ``` 156 | < 157 | elem: < 158 | name: "interfaces" 159 | > 160 | elem: < 161 | name: "interface" 162 | > 163 | elem: < 164 | name: "state" 165 | > 166 | elem: < 167 | name: "oper-status" 168 | > 169 | > 170 | ``` 171 | 172 | In this case, since the `interface` `PathElem` does not specify any keys, it should be interpreted to match all entries within the `interface` list. The same semantics can be specified by utilising an asterisk (`*`) for a particular `key` map entry's value, i.e.: 173 | 174 | ``` 175 | < 176 | elem: < 177 | name: "interfaces" 178 | > 179 | elem: < 180 | name: "interface" 181 | key: < 182 | key: "name" 183 | value: "*" 184 | > 185 | > 186 | > 187 | ``` 188 | 189 | #### Wildcards in paths 190 | 191 | * Wildcards are allowed to indicate all elements at a given subtree in the 192 | schema -- these are used particularly for telemetry subscriptions or 193 | `Get` requests. A single-level wildcard is indicated by specifying the `name` of a `PathElem` to be an asterisk (`*`). A multi-level wildcard is indicated by specifying the `name` of a `PathElem` to be the string `...`. 194 | 195 | * Wildcards may be used in multiple levels of the path, e.g., select all elements named `state` three levels deep: 196 | 197 | ``` 198 | < 199 | elem: < 200 | name: "interfaces" 201 | > 202 | elem: < 203 | name: "*" 204 | > 205 | elem: < 206 | name: "*" 207 | > 208 | elem: < 209 | name: "*" 210 | > 211 | elem: < 212 | name: "state" 213 | > 214 | > 215 | ``` 216 | 217 | * Per the specification above, wildcards may also appear as list key values. 218 | 219 | ``` 220 | < 221 | elem: < 222 | name: "interfaces" 223 | > 224 | elem: < 225 | name: "interface" 226 | key: < 227 | key: "name" 228 | value: "*" 229 | > 230 | > 231 | elem: < 232 | name: "state" 233 | > 234 | > 235 | ``` 236 | 237 | * Wildcards should not appear in paths returned by a device in 238 | telemetry notifications. 239 | 240 | * A single path element, including keyed fields, maybe be replaced by 241 | `...` to select all matching descendents. This is semantically equivalent 242 | to the empty element notation, `//`, in XPATH. 243 | 244 | ``` 245 | < 246 | elem: < 247 | name: "interfaces" 248 | > 249 | elem: < 250 | name: "interface" 251 | > 252 | elem: < 253 | name: "..." 254 | > 255 | > 256 | ``` 257 | 258 | * Select all `state` containers under interface 'eth0' 259 | ``` 260 | < 261 | elem: < 262 | name: "interfaces" 263 | > 264 | elem: < 265 | name: "interface" 266 | key: < 267 | key: "name" 268 | value: "eth0" 269 | > 270 | > 271 | elem: < 272 | name: "..." 273 | > 274 | elem: < 275 | name: "state" 276 | > 277 | > 278 | ``` 279 | 280 | ### Contributors 281 | * Paul Borman, Josh George, Kevin Grant, Chuan Han, Marcus Hines, Carl Lebsack, Anees Shaikh, Rob Shakir, Manish Verma (Google, Inc.) 282 | * Aaron Beitch (Arista) 283 | * Arun Satyanarayana (Cisco Systems) 284 | * Jason Sterne (Nokia) 285 | -------------------------------------------------------------------------------- /rpc/gnmi/decimal64-deprecation.md: -------------------------------------------------------------------------------- 1 | ## Deprecation of Decimal64 in gNMI 2 | 3 | **Updated**: April 28, 2022 4 | **Author**: Carl Lebsack 5 | 6 | ### Decision 7 | 8 | This document details the proposal (and decision, once approved) to deprecate and schedule removal of the Decimal64 message from gNMI and stipulate 9 | all Decimal64 values in the OpenConfig models be delivered as 10 | gNMI.TypedValue.double_val. 11 | 12 | ### Why is Decimal64 present today? 13 | 14 | OpenConfig models are defined in [YANG](https://tools.ietf.org/html/rfc6020), a 15 | modeling language which does not have a native IEEE-754 compliant binary 16 | floating point type and has instead chosen to only 17 | [support](https://tools.ietf.org/html/rfc6020#section-9.3) Decimal64 for real 18 | number representation. Because of this choice, models developed within YANG, 19 | including those of OpenConfig, have selected Decimal64 for data values where 20 | fractional representation is necessary. 21 | 22 | ### Why is Decimal64 problematic for gNMI? 23 | 24 | The primary problem is inefficiency which manifests in multiple ways by virtue 25 | of a misalignment of the natural encoding of the real data and the decimal 26 | encoding of the Decimal64 type. Before enumerating some of the inefficiencies in 27 | practical use, we’ll start with a brief discussion of the ultimate source of the 28 | data being modeled and the inappropriateness of Decimal64 for encoding. 29 | 30 | All values within the OpenConfig models that currently use the YANG Decimal64 type are 31 | fundamentally binary because they originate from 32 | [Analog to Digital Converters](https://en.wikipedia.org/wiki/Analog-to-digital_converter) 33 | (ADC) whereby a continuous analog signal, such as the laser power in an optical 34 | transceiver, is discretized into a digital binary representation. This means 35 | that despite the fact that we may render the outputs in a decimal form when 36 | presenting a human readable output, the data itself is binary. It would likely have been preferable to use a native floating point typedef (such as the `ieeefloat32` typedef that was defined within `openconfig-types`) as opposed to `decimal64`. The continued use of `decimal64` is primarily for backwards-compatibility reasons. 37 | 38 | Further, it is expected that a majority of clients using this data will 39 | ultimately be using binary floating point representation and Decimal64 is simply 40 | an awkward go-between induced by virtue of the YANG decision on only supporting 41 | a single encoding for real types. All time-series databases examined use binary 42 | floating point for real numbers. All major programming languages have native 43 | support for binary floating point as do the vast majority of modern CPU hardware 44 | where gNMI servers or its clients would likely run. 45 | 46 | Decimal64, on the other hand, is “intended for applications where it is 47 | necessary to emulate decimal rounding exactly, such as financial and tax computations.” 48 | ([Wikipedia](https://en.wikipedia.org/wiki/Decimal64_floating-point_format)) The 49 | decimal encoding is used for financial transactions because binary fractions 50 | have no precise representations of many decimal values, e.g. 0.1, and therefore 51 | can introduce error in computations where precise decimal rounding is required. 52 | 53 | Where the source of modeled data originates from ADC hardware, which 54 | themselves are subject to error and noise in their least significant bits, there 55 | is no need for precise rounding even in binary, let alone decimal. 56 | Additionally, often ADC are chosen based on cost with only as many bits as 57 | necessary to differentiate a particular analog signal into a minimum number of 58 | discrete values, often 16 bits or fewer. Given the lack of need for either the 59 | precision, size or accuracy of Decimal64 to represent the underlying data we can 60 | conclude that Decimal64 is in no way necessary and further enumerate some 61 | inefficiencies in using this format in gNMI. 62 | 63 | #### Poor infrastructure support for Decimal64 64 | 65 | Because Decimal64 was introduced in 2008, there is very limited support for the 66 | type natively in existing hardware, languages and libraries. This is most 67 | painful when integrating across systems and languages in places where gNMI is 68 | designed to operate because the interchange format of Protocol Buffers has 69 | [no native support of Decimal64](https://developers.google.com/protocol-buffers/docs/proto3#scalar). 70 | The workaround is to create a [complex type](https://github.com/openconfig/gnmi/blob/master/proto/gnmi/gnmi.proto#L186) 71 | using multiple integers as has been done in gNMI today. This complex type 72 | requires custom library code in every language to be used for encoding or 73 | decoding these fractional values. The code may not be complex but because the 74 | protocol buffer message is bespoke to gNMI, it will not be common with any other 75 | library code in existence for working with Decimal64 and thus has the potential 76 | for individual implementers to introduce bugs that are not easily detected. 77 | 78 | #### Unnecessary overhead of Decimal64 79 | 80 | Additionally, in the context of streaming telemetry, the custom type adds 81 | additional encoding and decoding steps to every value for every target server 82 | and every client that handles the data. This propagates both the library 83 | maintenance burden as well as inducing unnecessary computational overhead for 84 | the repeated conversions on both servers and clients. 85 | 86 | In addition to the redundant application level encoding and decoding overhead, 87 | the representation itself is excessive for both in-memory and on the wire 88 | transmission of the data. As stated above, the source of the original data is 89 | likely a low-bit-count ADC which can easily be encoded as a single 32bit binary 90 | floating point number. The message used in gNMI for Decimal64 uses two integer 91 | values, one 32 bit the other 64 bit for a total of 96 bits, and creates a nested 92 | structure which itself consumes additional space. Given that most language 93 | implementations of protocol buffers represent message types using pointers and 94 | most systems in which gNMI will be deployed are likely 64-bit, this is an 95 | additional 64-bit minimum for a total of 160 bits, or 5X overhead in storage. 96 | 97 | Furthermore, because the Decimal64 type is a complex message, there is 98 | additional computational overhead in the protocol buffer encoding and decoding 99 | as compared to the native protocol buffer float type. A simple Go benchmark 100 | (below) shows a 60% increase in protocol buffer encoding overhead. This does 101 | not include the previously mentioned application level encoding and decoding 102 | between the original float and a Decimal64 message, which does not exist when a 103 | native float type is used directly. 104 | 105 | On an Intel Xeon W-2135 @ 3.7GHz 106 | 107 | | | Double | Decimal64 | 108 | | BenchmarkEncode+Rand | 432.8 ns/op | 615.5 ns/op | 109 | | BenchmarkRand | 13.2 ns/op | 12.6 ns/op | 110 | | BenchmarkEncode only | 419.6 ns/op | 602.9 ns/op | 111 | 112 | ```go 113 | package decimal64 114 | 115 | import ( 116 | "math/rand" 117 | "testing" 118 | 119 | "github.com/golang/protobuf/proto" 120 | 121 | pb "github.com/openconfig/gnmi/proto/gnmi/gnmi_go_proto" 122 | ) 123 | 124 | func BenchmarkDoubleVal(b *testing.B) { 125 | for i := 0; i < b.N; i++ { 126 | f := rand.Float64() 127 | t := &pb.TypedValue{Value: &pb.TypedValue_DoubleVal{DoubleVal: f}} 128 | _, err := proto.Marshal(t) 129 | if err != nil { 130 | b.Fatalf("marshal error: %v", err) 131 | } 132 | } 133 | } 134 | 135 | func BenchmarkRandFloat64(b *testing.B) { 136 | for i := 0; i < b.N; i++ { 137 | rand.Float64() 138 | } 139 | } 140 | 141 | func BenchmarkDecimal64Val(b *testing.B) { 142 | for i := 0; i < b.N; i++ { 143 | df := rand.Int63() 144 | t := &pb.TypedValue{Value: &pb.TypedValue_DecimalVal{&pb.Decimal64{Digits: df, Precision: 5}}} 145 | _, err := proto.Marshal(t) 146 | if err != nil { 147 | b.Fatalf("marshal error: %v", err) 148 | } 149 | } 150 | } 151 | 152 | func BenchmarkRandInt63(b *testing.B) { 153 | for i := 0; i < b.N; i++ { 154 | rand.Int63() 155 | } 156 | } 157 | ``` 158 | 159 | #### Confusing both implementers and operators 160 | 161 | Another significant inefficiency of the use of Decimal64 is one of inter- 162 | organizational human communication. The gNMI specification and Protocol Buffer 163 | definition include two ways of rendering fractional values, Decimal64 and 164 | double_val. Because of this, we have some vendors using one or the other or both 165 | methods for various paths. Downstream clients need to handle both cases and 166 | convert Decimal64 to double where it appears. There is often the question of, 167 | “What matches the official OpenConfig schema”. The goal of this proposal is to 168 | codify that answer as double_val for gNMI. 169 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmi-config-subscriptions.md: -------------------------------------------------------------------------------- 1 | # gNMI Config Subscription Extension 2 | 3 | **Contributors:** Roman Dodin, Matthew MacDonald 4 | 5 | **Date:** July 29th, 2024 6 | 7 | **Version:** 0.1.0 8 | 9 | ## 1. Purpose 10 | 11 | Performing configuration management and handling configuration drift is one of 12 | the main features of a higher-level management system or orchestrator. 13 | Configuration drift occurs when a device's configuration changes independently 14 | of the expected configuration defined by the management system. Such changes 15 | may arise from manual interventions, automated processes outside the management 16 | system, or unexpected behavior. When drift is detected, the management system 17 | can either revert the configuration back to the expected configuration or 18 | incorporate the change by updating its records to include the new configuration 19 | as the expected configuration. The configuration management tasks focus on the 20 | effective retrieval and push of configuration values. 21 | 22 | Thus, having a synchronized configuration view between the management 23 | system and the network elements is key to enabling robust and near real-time 24 | configuration management. 25 | To enable this synchronization of configuration data, the gNMI Subscribe RPC 26 | can be used. The bidirectional streaming nature of this RPC enables fast 27 | and reliable sync between the management system and the devices it manages. 28 | 29 | Unfortunately, gNMI Subscribe RPC does not have an embedded mechanism to 30 | stream updates for the configuration values only as opposed to the Get RPC, 31 | which makes this RPC rather ineffective on YANG schemas that do not employ 32 | a separation of config and state elements by using distinct containers. 33 | 34 | This proposal introduces the Config Subscription extension that allows clients 35 | to indicate to servers that they are interested in configuration values only. 36 | 37 | gNMI Config Subscription Extension proto specification is defined in 38 | [gnmi_ext.proto]( 39 | https://github.com/openconfig/gnmi/blob/master/proto/gnmi_ext/gnmi_ext.proto 40 | ). 41 | 42 | ## 2. Definition 43 | 44 | A `ConfigSubscription` message is embedded as an extension message in the 45 | `SubscribeRequest` or `SubscribeResponse` proto messages. 46 | If the extension is embedded in a `SubscribeRequest`, the action field 47 | must be a `ConfigSubscriptionStart`. 48 | The presence of such an extension indicates to the target that the client 49 | wants to start a ConfigSubscription. The target must return notifications 50 | pertaining to data leaves that the target considers to be writable. 51 | If the subscription type is `ON_CHANGE`, the target must separate the 52 | notifications triggered by different commits using a 53 | `ConfigSubscriptionSyncDone` in a `SubscribeResponse` message. 54 | On the other hand, if the extension is embedded in a `SubscribeResponse`, the 55 | action field must be a `ConfigSubscriptionSyncDone`. This action is used by a 56 | target to indicate a commit boundary to the client. 57 | 58 | ## 2.1 Proto 59 | 60 | The extension contains a message called `ConfigSubscription` that carries 61 | one of 2 types of actions. `ConfigSubscriptionStart` or 62 | `ConfigSubscriptionSyncDone` 63 | 64 | ```proto 65 | // ConfigSubscription extension allows clients to subscribe to configuration 66 | // schema nodes only. 67 | message ConfigSubscription { 68 | oneof action { 69 | // ConfigSubscriptionStart is sent by the client in the SubscribeRequest 70 | ConfigSubscriptionStart start = 1; 71 | // ConfigSubscriptionSyncDone is sent by the server in the SubscribeResponse 72 | ConfigSubscriptionSyncDone sync_done = 2; 73 | } 74 | } 75 | 76 | // ConfigSubscriptionStart is used to indicate to a target that for a given set 77 | // of paths in the SubscribeRequest, the client wishes to receive updates 78 | // for the configuration schema nodes only. 79 | message ConfigSubscriptionStart {} 80 | 81 | // ConfigSubscriptionSyncDone is sent by the server in the SubscribeResponse 82 | // after all the updates for the configuration schema nodes have been sent. 83 | message ConfigSubscriptionSyncDone { 84 | // ID of a commit confirm operation as assigned by the client 85 | // see Commit Confirm extension for more details. 86 | string commit_confirm_id = 1; 87 | // ID of a commit as might be assigned by the server 88 | // when registering a commit operation. 89 | string server_commit_id = 2; 90 | // If true indicates that the server is done processing the updates related to the 91 | // commit_confirm_id and/or server_commit_id. 92 | bool done = 3; 93 | } 94 | ``` 95 | 96 | ## 2.2 Actions 97 | 98 | ### 2.2.1 ConfigSubscriptionStart 99 | 100 | A `ConfigSubscriptionStart` message is used by a gNMI client in a 101 | `SubscribeRequest` to indicate that it wants to start a ConfigSubscription. 102 | The target must respond exclusively with configuration data relevant to the 103 | created subscription. 104 | 105 | The base behavior of the `Subscribe` RPC remains unchanged: the target must 106 | respond with an initial set of updates, followed by a `SubscribeResponse` 107 | with the `sync_response` field set to true. However, if the updates_only 108 | field in the SubscribeRequest is set to true, the target should omit the 109 | initial updates and instead send only a SubscribeResponse with `sync_response` 110 | set to true, in accordance with the gNMI specification. 111 | 112 | ### 2.2.2 ConfigSubscriptionSyncDone 113 | 114 | The `ConfigSubscriptionSyncDone` message is included in a `SubscribeResponse` 115 | by a gNMI target to signify a commit boundary to the client. 116 | A commit boundary represents the completion of a specific set of changes 117 | associated with a commit. It confirms that all changes in the set have been 118 | successfully committed, with no errors reported by the interface used for the 119 | commit, such as gNMI, NETCONF, CLI, etc. 120 | [See Appendix - concurrent commits handling](#appendix-concurrent-commits-handling) 121 | 122 | The `ConfigSubscriptionSyncDone` message includes three fields: 123 | 124 | * `commit_confirm_id`: A commit confirm ID assigned by the client which 125 | initiated the commit. 126 | The commit can be initiated via gNMI (using the CommitConfirmed Extension), 127 | NETCONF, or any other management interface. Applicable only if the commit 128 | confirmed option is used. 129 | * `server_commit_id`: An optional internal ID assigned by the target. 130 | * `done`: If true, indicates that the server is done processing the updates 131 | related to the commit_confirm_id and/or server_commit_id. 132 | 133 | In the case a commit happens before the `sync_response: true` the server 134 | cannot send a `ConfigSubscriptionSyncDone` until the `sync_response: true` has 135 | been sent. The server may send the committed changes updates before the 136 | `sync_response: true`. 137 | 138 | ## 3. Configuration changes scenarios 139 | 140 | ### 3.1 Configuration changes without Commit Confirmed 141 | 142 | 1) The client subscribes to path P1 with the `ConfigSubscription` extension 143 | present with the action `ConfigSubscriptionStart`. 144 | 2) The server processes the subscription request as usual but will only send 145 | updates for the configuration schema nodes under the path P1. 146 | 3) The client sends a Set RPC with the configuration changes to the path P1 147 | **without** the `CommitConfirm` extension. 148 | 4) The server processes the Set RPC as usual and sends the updates for the 149 | configuration schema nodes under the path P1. 150 | 5) After all the configuration updates are sent, the server sends the 151 | `ConfigSubscriptionSyncDone` message to the client in a SubscribeResponse 152 | message. 153 | This message does not contain a `commit_confirmed_id` and may contain a 154 | `server_commit_id` 155 | 156 | ### 3.2 Configuration changes with Commit Confirmed 157 | 158 | 1) The client subscribes to the path P1 with the `ConfigSubscription` 159 | extension present with the action `ConfigSubscriptionStart`. 160 | 2) The server processes the subscription request as usual but will only send 161 | updates for the configuration schema nodes under the path P1. 162 | 3) The client sends a Set RPC with the configuration changes to the path 163 | P1 and **with** the `CommitConfirm` extension present. 164 | 4) The server processes the Set RPC as usual and sends the updates for 165 | the configuration schema nodes under the path P1. 166 | 5) As all the configuration updates are sent, the server sends the 167 | `ConfigSubscriptionSyncDone` message to the client in a SubscribeResponse 168 | message. 169 | This message must contain the the value of the `commit_confirmed_id` 170 | received in the Set RPC in step 4 and may contain a `server_commit_id`. 171 | 6) When the client sends the commit confirm message, the server confirms 172 | the commit and does not send any extra SubscribeResponse messages with the 173 | `ConfigSubscriptionSyncDone` message. 174 | 175 | ### 3.3 Configuration changes with Commit Confirmed and rollback/cancellation 176 | 177 | 1) The client subscribes to path P1 with the `ConfigSubscription` extension 178 | present with the action `ConfigSubscriptionStart`. 179 | 2) The server processes the subscription request as usual but will only send 180 | updates for the configuration schema nodes under the path P1. 181 | 3) The client sends a Set RPC with the configuration changes to the path P1 182 | and **with** the `CommitConfirm` extension present. 183 | 4) The server processes the Set RPC as usual and sends the updates for the 184 | configuration schema nodes under the path P1. 185 | 5) After all the configuration updates are sent, the server sends the 186 | `ConfigSubscriptionSyncDone` message to the client in a SubscribeResponse 187 | message. 188 | This message must contain the the value of the `commit_confirmed_id` received 189 | in the Set RPC in step 4. 190 | 6) When the commit confirmed rollback timer expires or a commit cancel message 191 | is received, the server: 192 | i. rolls back the configuration changes as per the Commit Confirm extension 193 | specification. 194 | ii. sends the new configuration updates for the path P1 as the configuration 195 | has changed/reverted. 196 | iii. sends the ConfigSubscriptionSyncDone message to the client in a 197 | `SubscribeResponse` message. 198 | This message must contain the the value of the `commit_confirmed_id` 199 | received in the Set RPC in step 4 and may contain a `server_commit_id`. 200 | 201 | ## Appendix: Concurrent commits handling 202 | 203 | ### Overlapping Update Streams 204 | 205 | In scenarios where updates from multiple configuration changes overlap during 206 | streaming, it is important to note that the `ConfigSubscriptionSyncDone` 207 | message does not guarantee that the state reflected by received updates 208 | corresponds exclusively to the commit referenced by the 209 | `ConfigSubscriptionSyncDone` message. For example: 210 | 211 | 1. Timeline: 212 | 213 | t = 0: Configuration change 1 is committed. 214 | t = 1: Streaming updates for configuration change 1 begins. 215 | t = Y (Y < N): Configuration change 2 is committed. 216 | t = Y + 1: Streaming updates for configuration change 2 begins. 217 | t = N: Streaming updates for configuration change 1 ends. 218 | t = Y + N: Streaming updates for configuration change 2 ends. 219 | 220 | 2. Implications: 221 | 222 | * Updates for paths impacted by configuration change 2 may be sent 223 | to the client before all updates for configuration change 1 are 224 | fully streamed. 225 | * When the client receives a `ConfigSubscriptionSyncDone` message 226 | for configuration change 1, it might already have received updates 227 | reflecting changes introduced by configuration change 2. 228 | * Coalescing updates (e.g., combining overlapping changes to a path like `/foo/bar`) 229 | If both configuration changes 1 and 2 modify `/foo/bar`, and the update for 230 | `/foo/bar` is delayed, the server may send only the final state of `/foo/bar` 231 | after configuration change 2. This approach optimizes performance but results 232 | in the client never receiving the updates for change 1. 233 | 234 | ### Guarantees 235 | 236 | The `ConfigSubscriptionSyncDone` message indicates that the server has completed 237 | processing all changes associated with the referenced commit. 238 | It does not guarantee that the client has received updates exclusively for that commit. 239 | 240 | If a client requires strict state guarantees, it must implement its own 241 | mechanisms to lock configuration changes between commits. For example: 242 | 243 | * Pausing further commits until the client confirms that all updates for the 244 | current commit are processed. 245 | * Implementing a client-side commit locking mechanism 246 | to avoid overlapping streams. 247 | -------------------------------------------------------------------------------- /rpc/gnmi/gnmignoissh-dialout-grpctunnel.md: -------------------------------------------------------------------------------- 1 | # gNMI/gNOI/ssh dial-out via grpctunnel 2 | 3 | **Contributors**: 4 | Carl Lebsack 5 | 6 | - [gNMI/gNOI/ssh dial-out via grpctunnel](#gnmignoissh-dial-out-via-grpctunnel) 7 | - [Introduction](#introduction) 8 | - [Generic gRPC tunnel](#generic-grpc-tunnel) 9 | - [Tunnel establishment](#tunnel-establishment) 10 | - [Target registration](#target-registration) 11 | - [Tunnel session establishment](#tunnel-session-establishment) 12 | - [Tunnel server to tunnel client session establishment](#tunnel-server-to-tunnel-client-session-establishment) 13 | - [Tunnel client to tunnel server session establishment](#tunnel-client-to-tunnel-server-session-establishment) 14 | - [Tunnel client to tunnel client session establishment](#tunnel-client-to-tunnel-client-session-establishment) 15 | - [Target subscription](#target-subscription) 16 | - [Select deployment use cases](#select-deployment-use-cases) 17 | - [Dial-out gNMI collector](#dial-out-gnmi-collector) 18 | - [Target-side gNMI tunnel client as a separate binary](#target-side-gnmi-tunnel-client-as-a-separate-binary) 19 | - [Target-side gNMI tunnel client embedded within a gNMI server](#target-side-gnmi-tunnel-client-embedded-within-a-gnmi-server) 20 | - [gNMI collector as a tunnel client with tunnel server as a separate binary](#gnmi-collector-as-a-tunnel-client-with-tunnel-server-as-a-separate-binary) 21 | - [gNMI collector with embedded tunnel server](#gnmi-collector-with-embedded-tunnel-server) 22 | - [SSH over tunnel](#ssh-over-tunnel) 23 | - [SSH local server connections redirected via a tunnel client](#ssh-local-server-connections-redirected-via-a-tunnel-client) 24 | - [SSH client dialing via a tunnel client](#ssh-client-dialing-via-a-tunnel-client) 25 | 26 | # Introduction 27 | There are several use cases that dictate the need to reverse the direction in which a TCP session is established between a client and server. There was a [detailed discussion](https://docs.google.com/document/d/1R0o_ZFoeIUSXZ3LYEZcx-9AvyCpUfNMdiIpzh-Sb8G8) about many options on how to support this use case either for a specific RPC (e.g. gNMI.Subscribe) or more broadly for multiple distinct RPCs, services or protocols. This document focuses on elaborating on the suggested deployment of a generic tunnel implemented over gRPC. This document is meant to provide an overview of the [grpctunnel project](http://github.com/openconfig/grpctunnel) on github. Presented below is an overview of the solution followed by several specific use cases to illustrate how they can leverage a common infrastructure API in various deployment scenarios. 28 | 29 | # Generic gRPC tunnel 30 | This section describes the generic tunnel API that can be used for various deployment options, some of which are enumerated in the subsequent section. In all cases, there is a base level tunnel API that consists of at least one tunnel server and one or more tunnel clients. Between each tunnel client and tunnel server there exists a single tunnel that is a single gRPC session. Within the gRPC session there is a single persistent Register RPC that is a bidirectional stream that handles the registration of targets, subscription of targets 31 | 32 | ## Tunnel establishment 33 | This is the process by which a tunnel client dials a tunnel server and invokes a persistent streaming grpctunnel.Register RPC to enable subsequent opening of one or more tunnel sessions by either the tunnel client or tunnel server and the optional registration of one or more targets also by either the tunnel client or tunnel server. 34 | 35 | The tunnel server must be network reachable by the tunnel client, and both the tunnel client and tunnel server must be configured with mutually compatible authentication mechanisms. This document does not aim to enumerate all mechanisms but for illustration, a given implementation should support both insecure TLS with no certificate verification and mTLS with bidirectional certificate verification. The encryption and verification of the tunnel is completely independent of any encryption, authentication and authorization that happens over a session within the tunnel. 36 | 37 | In practice, it is possible that a gNMI server could support both both dial-in and dial-out at the same time. It can accept connections via TCP over the tunnel, or accept connections via TCP over the local interface. 38 | 39 | The requirement for encrypted transport (TLS or mTLS) implies that if a tunnel session carries a gNMI RPC or ssh there will be double encryption, once at the tunnel layer and a second at the gNMI API layer. While it may be tempting to run the tunnel without encryption, doing so would eliminate the ability to perform authentication at the tunnel level, which is not recommended. Removing encryption at the API layer, such as gNMI or SSH, when carried over an encrypted tunnel is also not suggested as this breaks end-to-end authentication of the API client which is also not recommended. Without delving into a host of security concerns, we recommend that strong authentication and encryption be used both at the tunnel level and any API carried over the tunnel. 40 | 41 | ## Target registration 42 | This is the mechanism of the gRPC tunnel that can be leveraged to communicate information about the types of targets supported by either end of the tunnel. In this document, all use cases will assume that there is an explicit registration of available targets by at least one tunnel client or tunnel server, independent of requisition of sessions for those targets. All established sessions of the tunnel are to reference registered targets. The same grpctunnel.Register RPC is used to exchange both target registrations and session establishment messages and differentiated by the Registration oneof in the RegisterOp message. Target registration uses the Target message in that oneof. 43 | 44 | Target registration is the means by which one side of the tunnel advertises explicitly what is available for access by the other side. Although a server can be configured to reject targets, the most common case is for it to accept at least some targets, potentially based on type. For a tunnel client, it will only be sent targets if it specifically subscribes for them. See subscriptions below. 45 | 46 | For example, a tunnel client can convey to the tunnel server the unique name of an available target (target_id) and service for that target (target_type = “GNMI_GNOI”). Both target_id and target_type are strings to allow for the most flexible tunnel deployment options. The inclusion of a TargetType enum in the tunnel.proto enables the standardization of a set of predefined protocols to be carried by the tunnel. However, a protocol not included within the enum can still be used within the tunnel so long as the tunnel client and tunnel server agree on a common string for the type. 47 | 48 | Specifically, the target_id is not prescribed, but should be unique in a given deployment. Some examples of what can be used for the target_id include hostname, chassis serial number or mac address, management IP address. This target_id is assumed to be leveraged within gNMI as the [Path target field](https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#2221-path-target) in the case the tunnel is hosting a gNMI interface and allows a tunnel server to redirect a gNMI request over the corresponding tunnel session. The value of this id is expected to be defined by a network operator and should be configurable on each target to be provided when dialing out to a tunnel server. 49 | 50 | The target_type field, although flexible, is used in conjunction with target_id to differentiate among multiple protocols supported for the same target. It is a string to allow for arbitrary TCP protocols to be supported over the tunnel. However, standard protocols are explicitly included in the tunnel Protocol enum, (e.g. GNMI_GNOI, SSH), and the string value for that enumeration can be reliably used on both tunnel clients and tunnel servers. 51 | 52 | The diagram below shows the call flow of the tunnel establishment. It uses a 53 | standalone tunnel server for the purpose of this illustration. Alternative deployments will be discussed in more detail in [Select deployment use cases](#select-deployment-use-cases). Here each network device (gNMI server or target device) will establish a gRPC tunnel with one or more tunnel servers by finishing the registration step. After that, the network devices will accept future connections over the created tunnels. 54 | 55 | ![](img/grpctunnel-client-to-server-detail.png) 56 | 57 | ## Tunnel session establishment 58 | Once a tunnel is established between a tunnel client and tunnel server, the persistent bidirectional Registration RPC can be used to request a new gRPC session be established between the tunnel client and tunnel server to carry an arbitrary TCP session. There are three different ways a session can be established which are enumerated below. In all cases, the session is established only to targets previously registered on the tunnel server, either by the tunnel server itself, or by one of its tunnel clients. 59 | 60 | ### Tunnel server to tunnel client session establishment 61 | This is the simplest case to understand in the context of the gRPC tunnel solution as it enables reversing the dial semantics of TCP to enable a connection from tunnel server to tunnel client when there may be no direct network reachability in that direction. A tunnel client dials the tunnel server and registers one or more targets. The tunnel server then requests a new session to one of those targets over the Register stream, which is then established as a new Session RPC from the respective tunnel client. Once established, the new Session RPC can be used to carry any TCP session between the tunnel client and tunnel server. 62 | 63 | ![](img/tunnelservertotunnelclient.png) 64 | 65 | ### Tunnel client to tunnel server session establishment 66 | In this case, a target registered on the tunnel server can be contacted by a tunnel client. This case may seem unnecessary as the tunnel client already has network reachability to the tunnel server to establish the tunnel, but there are reasons that connections in this direction over the tunnel may be desirable. One such example is relying on the tunnel to authorize and authenticate connections, hiding available services from being publicly discoverable. 67 | 68 | After a tunnel client establishes a tunnel session to the tunnel server, the tunnel client can notify the tunnel server that it wishes to be notified of available tunnel server targets. The tunnel server can send a list of targets reachable behind it to the tunnel client. The tunnel client can then request and start a session to one of those targets over the tunnel. These services might be hosted on the tunnel server binary itself, or relayed to the ultimate service provider elsewhere either over a direct TCP dial (or by another tunnel connection, see Tunnel Client to Tunnel Client session establishment). 69 | 70 | ![](img/tunnelclienttotunnelserver.png) 71 | 72 | ### Tunnel client to tunnel client session establishment 73 | This final case is a special case of the tunnel client to tunnel server session establishment whereby the ultimate connection may be routed to another tunnel client. It illustrates the full power of the gRPC tunnel in that a tunnel server can act as a midpoint for connections between tunnel clients. A tunnel client can, in addition to or instead of registering its available targets, request to be notified of targets reachable by the tunnel server. This special case focuses on the ability to route a single session be relayed by concatenating two independent tunnel client sessions within the tunnel server. 74 | 75 | ![](img/tunnelclienttotunnelclient.png) 76 | 77 | ## Target subscription 78 | A tunnel client has the option of getting a subscription of all targets registered with the tunnel. After the Tunnel is established, a tunnel client sends a Subscribe message (optionally specifying a target type) and receives a stream of Target messages from the tunnel server for all currently registered targets followed by a Subscribe accept. Future target additions that match the subscription type will be forwarded to the tunnel client as Target messages at the time they are added. A subscription is used by a client of the selected tunnelled protocol (e.g. an ssh client for ssh or a gNMI telemetry collector for a gNMI.Subscribe) to discover the list of targets reachable via a given tunnel server. 79 | 80 | # Select deployment use cases 81 | ## Dial-out gNMI collector 82 | In this example there are a group of gNMI target devices that are configured to initiate a tunnel connection to a common gNMI collector. The collector does not know a priori which devices will be connected and will collect from all target devices that connect. 83 | 84 | ![](img/gnmi_dialout.png) 85 | 86 | To implement the above, there are multiple options on both the device and collector side with how they integrate to the gRPC tunnel. Below will illustrate the variants on each side of the tunnel independently as they are interchangeable across the tunnel interface. 87 | 88 | ### Target-side gNMI tunnel client as a separate binary 89 | This option is available to a target implementer that wants to leverage the tunnel implementation as provided in Go without the need to directly integrate the code into an existing gNMI server which might be implemented in another language. The existing gNMI Server can be run without modification. The tunnel client can be launched as a separate binary that establishes a tunnel to a remote collector and forwards all gNMI requests over tunnel sessions to the running tunnel server via a local TCP connection between the two binaries. 90 | 91 | ![](img/grpctunnelclient_standalone.png) 92 | 93 | The grpctunnel repository has an [example tunnel client application](https://github.com/openconfig/grpctunnel/blob/master/cmd/client/client.go) that can be configured to perform this task by connecting to a remote tunnel server and redirecting incoming sessions over a TCP connection dialed from the tunnel client to the local gNMI server. 94 | 95 | ### Target-side gNMI tunnel client embedded within a gNMI server 96 | This option provides a means to deploy the tunnel client as a library within an application that hosts a gNMI server. In this example, a single binary acts as both the gNMI server and the tunnel client. A tunnel listener is installed in parallel to the TCP listener in the gRPC service for gNMI. 97 | 98 | ![](img/grpctunnelclient_embedded.png) 99 | 100 | ### gNMI collector as a tunnel client with tunnel server as a separate binary 101 | In this option, the gNMI Collector dials to the tunnel server to gain discovery and reachability access to targets connected to the tunnel server. Subsequent gNMI Subscribe requests can be issued as connections over the tunnel to the targets as in the diagram above for Tunnel client to tunnel client session establishment. 102 | 103 | ![](img/grpctunnelclient_embed_gnmicollector.png) 104 | 105 | ### gNMI collector with embedded tunnel server 106 | In this instance the gNMI collector binary also hosts the tunnel server directly, allowing targets to connect. Upon tunnel establishment, the target registration can trigger the collector to issue gNMI.Subscribe calls back over the respective established tunnel. 107 | 108 | ![](img/grpctunnelserver_embed_gnmicollector.png) 109 | 110 | ## SSH over tunnel 111 | ### SSH local server connections redirected via a tunnel client 112 | No modification is done for the local SSH server. A tunnel client is configured to accept incoming connections for SSH and redirect over a local TCP dial. The tunnel client can be either a standalone client or could be embedded in another binary, such as a gNMI server. The connection path looks like that for Target-side gNMI tunnel client as a separate binary, above. 113 | 114 | ### SSH client dialing via a tunnel client 115 | SSH clients can dial to a target by proxying through a tunnel client to a tunnel server to connect to an ssh target which is connected to the same tunnel server via its own client. The ProxyCommand option can be used to establish a TCP connection between the ssh client and server over a tunnel session between the two. 116 | 117 | `$ ssh -o ProxyCommand=”tunnel_client -dial -type SSH”` 118 | -------------------------------------------------------------------------------- /ietf/drafts/draft-openconfig-rtgwg-gnmi-spec-01.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | gRPC Network Management Interface (gNMI) 7 | 8 | 9 | 10 | 11 | 12 | Google 13 |
14 | 15 | 1600 Amphitheatre Pkwy 16 | Mountain View 17 | CA 18 | 94043 19 | US 20 | 21 | borman@google.com 22 |
23 |
24 | 25 | Google 26 |
27 | 28 | 1600 Amphitheatre Pkwy 29 | Mountain View 30 | CA 31 | 94043 32 | US 33 | 34 | hines@google.com 35 |
36 |
37 | 38 | Google 39 |
40 | 41 | 1600 Amphitheatre Pkwy 42 | Mountain View 43 | CA 44 | 94043 45 | US 46 | 47 | csl@google.com 48 |
49 |
50 | 51 | Google 52 |
53 | christopher.morrow@gmail.com 54 |
55 |
56 | 57 | 58 | Routing 59 | 60 | 61 | 62 | This document describes the gRPC Network Management Interface (gNMI), 63 | a network management protocol based on the gRPC framework. gNMI 64 | supports retrieval and manipulation of state from network elements 65 | where the data is represented by a tree structure, and addressable by 66 | paths. The gNMI service defines operations for configuration 67 | management, operational state retrieval, and bulk data collection via 68 | streaming telemetry. The authoritative gNMI specification is 69 | maintained at . 70 | 71 | 72 |
73 | 74 | 75 |
76 | 77 | This document provides an overview of gNMI, a gRPC-based protocol for state 78 | management on network elements .The gRPC Network 79 | Management Interface (gNMI) supports modification and retrieval of 80 | configuration, as well as control and transmission telemetry streams from a 81 | network element to a data collection system.This allows a single 82 | implementation on the network element, as well as a single NMS element to 83 | interact with the device via telemetry and configuration RPCs. 84 | 85 | 86 | All messages within the gRPC service definition are defined as protocol 87 | buffers (specifically proto3) .gRPC service 88 | definitions are described using the relevant features of the protobuf 89 | IDL.The authoritative protobuf definition is maintained in .The current, authoritative version of the gNMI 91 | specification is available at . 92 | 93 | 94 | gNMI offers an alternative to management protocols such as NETCONF and RESTCONF 96 | with implementations on devices from multiple vendors.gNMI derives a number 97 | of benefits from being built on gRPC and HTTP/2, including modern security 98 | mechanisms, bidirectional streaming, binary framing, and a wide variety of 99 | language bindings to simplify integration with management applications.With 100 | protobuf encoding, it also provides significant efficiency advantages over 101 | XML serialization with a 3 to 10 times reduction in data volume (see the 102 | "Developer Guide" in for examples).A number of open 103 | source tools and reference implementations are available from the OpenConfig 104 | working group . 105 | 106 |
107 | 108 |
109 | 110 | Throughout this document the following terminology is used: 111 | 112 | 113 | 114 | Telemetry - refers to streaming data relating to underlying characteristics of the device - either operational state or configuration. 115 | Configuration - elements within the data schema which are read/write and can be manipulated by the client. 116 | Target - the device within gNMI which acts as the owner of the data that is being manipulated or reported on. Typically this will be a network device. 117 | Client - the device or system using gNMI to query/modify data on the target, or act as a collector for telemetry data. Typically this will be a network management application. 118 | 119 | 120 |
121 | 122 |
123 | The sections below provide an overview of the gNMI protocol operations, leaving a detailed discussion to the full specification in . 124 | 125 | 126 | 127 |
128 | gNMI is often used to carry payloads that contain data instances of YANG schemas (for example based on OpenConfig models ), but can be used for any data with the following characteristics: 129 | 130 | 131 | 132 | structure that can be represented by a tree, where nodes can be uniquely identified by a path consisting of node names, or node names coupled with attributes; 133 | values can be serialised into a scalar object. 134 | 135 | 136 | Values may be serialised to native protobuf scalar types, structured data types (e.g. as JSON or protobuf object), or a schema language-specific type (e.g., YANG Decimal64). 137 | 138 | Data in gNMI is addressed by a path, which is represented as a structured list of elements, each with associated attributes if present. For example, the human-readable path "/interfaces/interface[name=eth0]/config/description" is represented as a text-encoded protobuf as: 139 | 140 |
141 | path: < 142 | elem: < 143 | name: "interfaces" 144 | > 145 | elem: < 146 | name: "interface" 147 | key: < 148 | key: "name" 149 | value: "eth0" 150 | > 151 | > 152 | elem: < 153 | name: "config" 154 | > 155 | elem: < 156 | name: "description" 157 | > 158 | > 159 |
160 | For more efficient handling of paths, gNMI supports a path prefix that is applied to every path in a message. Paths in gNMI are always absolute, constructed by concatenating the prefix with the path. 161 | 162 |
163 | 164 | 165 |
166 | gNMI is designed with a small number of base remote procedure calls (RPCs) to simplify client and target implementations. This section provides a high-level overview of each RPC. Full details are available in . 167 | 168 | 169 |
170 | The Capabilities RPC allows a client to interrogate a gNMI target to learn about supported features. The primary information returned by a target include the set of models it supports, the data encodings supported, and the version of the gNMI protocol it is using. The model information is expected to be based on a published model catalog . 171 | 172 |
173 | 174 |
175 | Subscribe is a bidirectional streaming RPC that allows clients and targets to send independent sequences of telemetry messages. Clients may subscribe to notifications for telemetry data by specifying a path to the desired data and a mode (in addition to other parameters). gNMI supports several modes, but the two common use cases are for periodically sampled data, such as counters, and event-driven data in which a notification is sent only when the corresponding data value changes. In response to a subscription, the target sends a stream of telemetry notifications that contain a timestamp, path, and updated value. Multiple updates may be included in a single RPC message. 176 | 177 | A streaming RPC for telemetry has the benefit of not requiring the target to collect, stage in memory, and serialize all of the requested data at once. The target is able to send data as soon as it is available, and can manage its resources to avoid becoming overloaded when sending a large volume of data. 178 | 179 |
180 | 181 |
182 | Set is a unary RPC (i.e., single request and single response) that is sent by a client to update the state of the target. Set includes several operation types whereby data may be updated, deleted, or replaced. A Set RPC may include multiple operations -- the target is expected to treat each RPC as a transaction such that if all included operations cannot be completed successfully, the target's state is unchanged. Clients using the gNMI Set RPC pre-stage a set of update operations into a single Set RPC call, which must be either completely applied, or rolled back - eliminating the complex, long-lived candidate changes used in other protocols. 183 | 184 |
185 | 186 |
187 | Get is also a unary RPC that allows clients to request an immediate snapshot of the current state from the target, specified by a path. The target is expected to collect the data when the request is received, and serialize it for immediate transmission to the client. Where supported, gNMI allows the client to specify the type of data that should be returned (e.g., configuration state, operational state, etc.). 188 | 189 |
190 |
191 |
192 | 193 |
194 | The sections below describe additional features and operations in gNMI. 195 | 196 |
197 | Rather than defining application-level error messates, gNMI leverages native error handling mechanisms in gRPC in which canonical error codes and context information are part of the Status message in every RPC. The gNMI specification provides guidance on how gNMI error conditions should be mapped to canonical error codes. 198 | 199 |
200 | 201 |
202 | While the base gNMI protocol is deliberately limited to a set of simple operations, some use cases require additional parameters that may be only applicable in those scenarios. gNMI extensions define a common way to add new payload to gNMI RPCs for these use cases without requiring changes in the core protocol specification. 203 | 204 |
205 |
206 | 207 |
208 | 209 | gNMI allows access and manipulation of state on network devices, hence it requires careful consideration of security implications including authentication and authorization of RPCs. The gNMI specification and companion document discuss the considerations in more detail. 210 | 211 | 212 |
213 | 214 |
215 | 216 | No IANA considerations at this time. In the future there may be a request for a protocol registry 217 | entry and well-known port allocation. 218 | 219 |
220 | 221 |
222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | gRPC 233 | The gRPC authors 234 | 235 | 236 | 237 | 238 | 239 | Protocol buffers 240 | Google 241 | 242 | 243 | 244 | 245 | 246 | gnmi.proto 247 | OpenConfig operator working group 248 | 249 | 250 | 251 | 252 | 253 | gRPC Network Management Interface (gNMI) v0.6.0 254 | OpenConfig operator working group 255 | 256 | 257 | 258 | 259 | 260 | gNMI Github repository 261 | OpenConfig operator working group 262 | 263 | 264 | 265 | 266 | 267 | Extensions to gNMI 268 | OpenConfig operator working group 269 | 270 | 271 | 272 | 273 | 274 | gNMI Authentication and Encryption 275 | OpenConfig operator working group 276 | 277 | 278 | 279 | 280 | 281 | OpenConfig 282 | OpenConfig operator working group 283 | 284 | 285 | 286 | 287 | 288 | 289 |
290 |
291 | 292 | 293 | Replaced specification content with overview material and reference to normative reference to the gNMI specification document 294 | 295 | Updated to reflect changes in the gNMI specification and introduction of gNMI extensions. 296 | 297 | 298 | 299 |
300 |
301 | 302 | 303 |
304 | 305 | 306 |
307 | -------------------------------------------------------------------------------- /ietf/drafts/draft-openconfig-rtgwg-local-routing-00.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Data Model for Locally Generated Routes in Service Provider Networks 6 | 7 | Google 8 |
9 | 10 | 1600 Amphitheatre Pkwy 11 | Mountain View 12 | CA 13 | 94043 14 | US 15 | 16 | aashaikh@google.com 17 |
18 |
19 | 20 | Google 21 |
22 | 23 | 1600 Amphitheatre Pkwy 24 | Mountain View 25 | CA 26 | 94043 27 | US 28 | 29 | jgeorge@google.com 30 |
31 |
32 | 33 | 34 | 35 | Verizon Communications 36 |
37 | 38 | 40 Sylvan Rd. 39 | Waltham 40 | MA 41 | US 42 | 43 | feihong.x.chen@verizon.com 44 |
45 |
46 | 47 | 48 | 49 | Routing 50 | 51 | 52 | This document defines a YANG data model for configuring and 53 | managing locally generated routes in a vendor-neutral way and 54 | based on operational best practice. Locally generated routes 55 | are those created by configuration, rather than by dynamic 56 | routing protocols. Such routes include static routes, locally 57 | created aggregate routes for reducing the number of constituent 58 | routes that must be advertised, summary routes for IGPs, etc. 59 | 60 | 61 |
62 | 63 | 64 |
65 | 66 | This document describes a simple YANG 67 | data model for locally generated routes, i.e., those not created by 68 | dynamic routing protocols. These include static routes, locally 69 | created aggregate routes, summary routes for IGPs, etc. 70 | 71 |
72 | 73 | This model expresses locally generated routes as generically as 74 | possible, avoiding configuration of protocol-specific attributes 75 | at the time of route creation. This is primarily to avoid 76 | assumptions about how underlying router implementations handle 77 | route attributes in various routing table data structures they 78 | maintain. Hence, the definition of locally generated routes 79 | essentially creates 'bare' routes that do not have any protocol- 80 | specific attributes. 81 | 82 | 83 | When protocol-specific attributes must be attached to a route 84 | (e.g., communities on a locally defined route meant to be 85 | advertised via BGP), the attributes should be attached via a 86 | protocol-specific policy after importing the route into the 87 | protocol for distribution (again via routing policy). This 88 | model is intended to be used with the generic routing policy 89 | framework defined in . 91 | 92 | 93 | This model does not aim to be feature complete -- it is a 94 | subset of the configuration parameters available in a variety 95 | of vendor implementations, but supports widely 96 | used constructs for managing local routes. Model development 97 | has been primarily driven by examination of actual configurations 98 | across operator networks. 99 | 100 | 101 | While this document provides an overview of the model, the 102 | most current and authoritative version is available in the 103 | public YANG model repository. 104 | 105 |
106 |
107 | 108 |
109 | 110 | In this initial version of the local routing model, two primary 111 | types of locally generated routes are supported, static routes 112 | and local aggregates. Static routes are manually configured routes 113 | with a defined prefix and next-hop. The model support next-hops 114 | specified as an IP address, interface, or a special defined value, 115 | e.g., DISCARD to prevent forwarding for the specified prefix. 116 | Aggregate routes are used to summarize constituent routes and 117 | avoid having to advertise each constituent individually, and hence 118 | increase routing table size. Aggregate routes are not used for 119 | forwarding, rather they are "activated" when a constituent route 120 | with a valid next hop is present in the IP routing table. 121 | 122 | 123 | The model structure is shown below: 124 | 125 |
126 | 127 | +--rw local-routes 128 | +--rw config 129 | +--ro state 130 | +--rw static-routes 131 | | +--rw static* [prefix] 132 | | ... 133 | +--rw local-aggregates 134 | +--rw aggregate* [prefix] 135 | ... 136 | 137 |
138 | 139 | Note that the model follows the convention of representing 140 | configuration and operational state at the leaves of the 141 | tree, based on recommendations in . 142 | In this case, the operational state consists primarily of the applied 143 | configuration. 144 | 145 |
146 | 147 |
148 | 149 | In many vendor implementations, local routes may be annotated with 150 | various route attributes or policies. For example, when creating 151 | a locally generated aggregate route, it is often possible to specify 152 | BGP communities which can then be 153 | used when filtering the routes 154 | sent to particular neighbors or peer groups. IGP implementations 155 | such as IS-IS and OSPF have similar capability to create "summary" 156 | routes that serve a similar purpose to BGP aggregates. 157 | 158 | 159 | Since these and other local routes are conceptually similar from 160 | an operator standpoint, there is a desire to create a single 161 | model that may be used generically to address a number of use cases. 162 | The approach taken in this model is to define locally generated 163 | routes as "bare" routes, i.e., without any protocol-specific attributes 164 | such as BGP communities, IGP tags, etc. Instead, these attributes are 165 | expected to be added via policy when locally generated routes are 166 | injected into a particular protocol for subsequent advertisement. 167 | 168 | 169 | Another important motivation for not including protocol-specific 170 | attributes when configuring local routes is that it assumes 171 | implementations can support the association of a variety of attributes 172 | with a route. While this may be true in some implementations, others 173 | may segregate routing tables for different protocols into different 174 | data structures such that it would not be possible to attach attributes 175 | from, say BGP, onto an OSPF route. For this reason, we constrain 176 | attributes on locally generated routes to be attached via policy as 177 | they are imported into different protocols. 178 | 179 | 180 | For example, consider the case of configuring a new prefix to be 181 | advertised to neighbors via BGP. Using the local routing model 182 | and the routing policy model in , one way to do this is enumerated below: 184 | 185 | 186 | 187 | 188 | Declare a static route for the advertised prefix using 189 | the local routing model (e.g., with a next hop set to DISCARD). 190 | This route is placed in the IP routing table. 191 | 192 | 193 | Define a policy to add BGP attributes to the route -- the 194 | policy would match on the prefix and the origin of the route 195 | (i.e., STATIC) and its action could be to add a BGP 196 | community. 197 | 198 | 199 | Apply the BGP policy as an import policy within BGP, e.g., 200 | using the apply-policy statement in the policy model, to 201 | import the route into BGP. 202 | 203 | 204 | Export the route to neighbors using an export policy as 205 | usual, filtering on the added community attribute if appropriate. 206 | 207 | 208 | 209 | 210 | The step of creating a policy to add BGP (or other 211 | protocol-specific) attributes to the route is optional 212 | if an operator simply wishes to export the route to neighbors, 213 | as opposed to also filtering on attributes that are assumed to 214 | be present on the locally generated route. 215 | 216 | 217 | This version of the model does support the capability to specify 218 | a generic route tag that can be associated with locally generated 219 | routes (i.e., both statics and aggregates). The tag can be used 220 | to filter routes that are imported into different routing protocols, 221 | for example, or to control which routes are exported to a neighbor. 222 | The route tagging capability may be refined further as more 223 | implementor feedback is incorporated into the model. 224 | 225 |
226 | 227 |
228 | 229 | Routing configuration has a significant impact on network operations, 230 | and as such any related model carries potential security risks. 231 | 232 | 233 | YANG data models are generally designed to be used with the 234 | NETCONF protocol over an SSH transport. This provides an 235 | authenticated and secure channel over which to transfer 236 | configuration and operational data. Note that use of 237 | alternate transport or data encoding (e.g., JSON over HTTPS) 238 | would require similar mechanisms for authenticating and 239 | securing access to configuration data. 240 | 241 | 242 | Most of the data elements in the local routing model could be 243 | considered sensitive from a security standpoint. Unauthorized 244 | access or invalid data could cause major disruption. 245 | 246 | 247 |
248 | 249 |
250 | 251 | This YANG data model and the component modules currently use 252 | a temporary ad-hoc namespace. If and when it is placed on redirected for 253 | the standards track, an appropriate namespace URI will be 254 | registered in the IETF XML Registry". 255 | The routing policy YANG modules will be registered in the 256 | "YANG Module Names" registry [RFC6020]. 257 | 258 |
259 | 260 |
261 | 262 | The local routing model is described by the YANG module below. 263 | 264 | 265 |
266 | file local-routing.yang 268 | 269 | 270 | ]]> 271 | 272 |
273 |
274 | 275 |
276 | 277 | 278 | Below we show an example of XML-encoded configuration data using 279 | the local routing model, in conjunction with the policy and BGP models to illustrate how local 282 | aggregate routes are defined and distributed into protocols. Although 283 | the example focuses on BGP, the aggregate routes may be used with other 284 | routing protocols (e.g., IGPs) as mentioned in Section 285 | . Note that 286 | the XML has been modified to improve readability. 287 | 288 | 289 |
290 | 292 | ]]> 293 | 294 |
295 | 296 |
297 | 298 |
299 | 300 | 301 | 302 | 303 | 304 | YANG - A Data Modeling Language for 305 | the Network Configuration Protocol (NETCONF) 306 | 308 | Tail-f Systems 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | A Border Gateway Protocol 4 (BGP-4) 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | The IETF XML Registry 334 | 336 | Verisign, Inc. 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | A Data Model for Locally Generated Routes in Service Provider Networks 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 |
358 | The authors are grateful for valuable contributions to this 359 | document and the associated models from: Phil Bedard, Kevin Brintnall, 360 | Matt John, Marcus Hines, and Eric Osborne. 361 | 362 |
363 |
364 |
365 | -------------------------------------------------------------------------------- /ietf/drafts/draft-openconfig-rtgwg-network-instance-01.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Data Model for Network Instances in Service Provider Networks 6 | 7 | 8 | 9 | 10 | Routing 11 | 12 | 13 | 14 | This document defines a YANG data model for configuring and 15 | managing forwarding instances on a network device - focused 16 | primarily on deployments in service provider networks. The 17 | model is vendor-neutral and based on operational 18 | requirements expressed by operators. A 'network instance' is 19 | defined to be a discrete forwarding table on a network 20 | element, which contains Layer 3 and/or Layer 2 forwarding 21 | entries. Each network instance may instantiate its own 22 | sets of protocols which control installation of 23 | forwarding entries into one or more tables (which may be 24 | Layer 2 FIBs, or Layer 3 RIBs). 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | Within service provider networks, it is typical for a 33 | network element to maintain multiple forwarding tables, 34 | allowing the network to support multiple topologies. For 35 | instance, a service provider may offer Layer 2 or Layer 3 36 | VPN services to its customers - which requires a forwarding 37 | table per customer to be maintained on a network element. In 38 | other cases, multiple L3 services may be deployed to allow 39 | services such as Internet connectivity and private 40 | topologies to be maintained on a device. 41 | 42 | 43 | This YANG data model defines a 44 | construct which can be used to configure and retrieve 45 | operational state related to such instances. 46 | 47 |
48 | 49 | The concept of maintaining multiple Layer 2 virtual switch 50 | instances (VSIs) and/or multiple Layer 3 virtual routing 51 | and forwarding (VRF) tables is common on network elements 52 | that are deployed in service provider networks. However, 53 | within such networks there are requirements for a network 54 | instance to run both Layer 2 and Layer 3 routing 55 | protocols, or contain routed interfaces (e.g., a VPLS 56 | service where there is a Layer 3 interface within it, for 57 | subscriber termination or to act as a default gateway). 58 | For this reason, the intention of the model presented 59 | here is to define a generic construct which allows 60 | isolation of a forwarding table which may contain Layer 3 61 | RIB entries, Layer 2 FIB entries, or a combination both. 62 | This differs to the approach taken in other models, which 63 | tend to focus on solely L2 VSIs or L3 VRFs. An instance 64 | within the model is referred to as network instance - and 65 | may be configured to support L3 RIB entries only (i.e., be 66 | functionally equivalent to a VRF), L2 FIB entries only 67 | (i.e., act as a VSI) or support a combination of both. 68 | 69 | 70 | The model presented in this document is explicitly biased 71 | towards deployments on service provider network equipment, 72 | as discussed between members of the OpenConfig project. 73 | 74 |
75 |
76 |
77 |
78 | 79 | module: openconfig-network-instance 80 | +--rw network-instances 81 | +--rw network-instance* [name] 82 | +--rw name -> ../config/name 83 | +--rw config 84 | ... 85 | +--ro state 86 | ... 87 | +--rw inter-instance-policies 88 | | +--rw apply-policy 89 | ... 90 | +--rw table-connections 91 | | +--rw table-connection* [src-table dst-table] 92 | | +--rw src-table -> ../config/src-table 93 | | +--rw dst-table -> ../config/dst-table 94 | ... 95 | | +--rw apply-policy 96 | ... 97 | +--rw tables 98 | | +--rw table* [table-name] 99 | ... 100 | +--rw interfaces 101 | .... 102 | +--rw connection-points 103 | | +--rw connection-point* [connection-point-id] 104 | ... 105 | +--rw protocols 106 | +--rw protocol* [identifier name] 107 | ... 108 | +--rw static 109 | ... 110 | +--rw aggregate 111 | ... 112 | 113 |
114 | 115 | The key elements of the network instance model shown in 116 | the above outline tree view are: 117 | 118 | 119 | Type of network instance and key configuration parameters 120 | that relate to it (e.g., configuration of a route 121 | distinguisher for L3 routing instance). 122 | 123 | 124 | Policies which define how the instance exchanges routes 125 | with other instances - for example, allowing forwarding 126 | entries to be leaked between a global and private network 127 | instance. 128 | 129 | 130 | The individual tables that are maintained by a network 131 | instance. This caters for the approach whereby an 132 | implementation maintains per-protocol tables - and it is 133 | possible to examine these tables separately. The choice to 134 | implement this table definition is an open issue - as 135 | discussed in . Along 136 | with this table definition, a set of policies determining 137 | how entries are leaked between the tables is defined. 138 | 139 | 140 | Connections between the different tables that are 141 | maintained by the network instance. Where protocols 142 | populate individual tables, such connections facilitate 143 | leaking of routes between individual protocols (by means 144 | of populating entries from one into the table of the 145 | other). 146 | 147 | 148 | The interfaces associated with a certain network instance 149 | - the current implementation assumption (as demonstrated 150 | in the openconfig-interfaces models) is that configuration 151 | parameters that relate directly to the interface (e.g., 152 | IP addressing) are configured directly under the interface 153 | construct. This requires that a network instance must have 154 | a means to be able to associate itself with an interface. 155 | 156 | 157 | A logical grouping of local or remote interfaces into 158 | 'connection points' utilised by a number of Layer 2 159 | forwarding approaches (e.g., redundancy for attachment 160 | points for PWE or L2VPN services). This allows interfaces 161 | which are associated with the network instance to be 162 | associated with one another, and hence referenced as a 163 | group. This construct can be used to represent redundant 164 | interfaces for a P2P L2VPN - and is extensible to support 165 | Ethernet segments for other L2VPN types. 166 | 167 | 168 | A list of the protocols that are instantiated under the 169 | network instance. The protocols that are defined in are 171 | included directly such that forwarding entries generated 172 | as static or aggregate routes can be matched in a routing 173 | policy. Other protocols, such as BGP (for which the data 174 | model is defined in would augment this list to include their own 176 | configuration options). It should be noted that the list 177 | of protocols is not keyed directly on the protocol name, 178 | but rather also includes an identifier for that instance. 179 | This supports cases where a single network instance may 180 | run multiple instances of a protocol. 181 | 182 | 183 | 184 | 185 | It is expected that all devices maintain at least one network 186 | instance, which represents the default (or global) forwarding 187 | table of the device. Additional instances are intended to 188 | support virtual instances, such as VSIs and VRFs. 189 | 190 | 191 | Where base configuration is required for such instances to be 192 | utilised (e.g., an route distinguisher value is required) then 193 | this is configured globally for each network instance. It 194 | expected that additional parameters, such as the encapsulation 195 | utilised for the instance will be added in future revisions of 196 | the model. 197 | 198 | 199 | Policies for leaking of routes between instances and tables 200 | leverage as a 201 | policy framework. This allows definition of 'import' policies 202 | (allowing a pull model) or export policies (allowing a push 203 | model) to be utilised for installation of entries into a local 204 | or remote network instance. The same framework is utilised to 205 | leak prefixes between multiple tables that are instantiated 206 | under an individual network instance. 207 | 208 |
210 | 211 | Whilst the initial focus of parameters in the 212 | model is to allow the instantiation of attributes related to 213 | Layer 3 forwarding constructs - it is expected that other 214 | configuration parameters, such as the definition of 215 | 'cross-connections' between local and/or remote interfaces 216 | or connection points can be utilised to represent forwarding 217 | constructs within the network instance. 218 | 219 | 220 | The addition of this to the model is still a 221 | work-in-progress. The inclusion of the connection point 222 | configuration and state parameters is intended to 223 | demonstrate how L2 and L3 constructs can co-exist with one 224 | another within the model. 225 | 226 |
227 |
228 |
229 |
231 | 232 | Some implementations maintain a single table into which all 233 | protocols install entries. Each protocol is then configured 234 | to explicitly import entries from that table into their 235 | local 'export' table. Others maintain multiple RIBs and 236 | require explicit connections to be made between these tables 237 | such that entries from one protocol are made available to 238 | another. 239 | 240 | 241 | There are essentially two alternatives for how this is 242 | modelled in the network-instance model: 243 | 244 | 245 | Allow each protocol to specify a 'target-table' that 246 | indicates the table that its entries are to be installed 247 | into. In the case that the same target table is 248 | specified for multiple protocols, implicit import/export 249 | configuration between tables could be created on 250 | implementations that implement multiple RIBs. Explicit 251 | configuration can be utilised to explicitly allow an 252 | operator to leak between tables in the case that 253 | multiple target tables are specified. It should be noted 254 | that in fact, protocols that support multiple address 255 | families need to allow specification of the target table 256 | on a per-address-family basis. 257 | 258 | 259 | Assume that all protocols implement their own target 260 | tables. In this case, explicit configuration is utilised 261 | to leak between them. Implementations that do not 262 | support such per-protocol tables could implicitly 263 | generate the configuration that results in forwarding 264 | entries being leaked between the tables such that the 265 | appearance of a single target-table is maintained. 266 | 267 | 268 | As per the discussion in 269 | currently, this model chooses the former implementation 270 | approach. 271 | 272 |
273 |
274 |
275 | 276 | 277 | Routing configuration has a significant impact on network operations, 278 | and as such any related model carries potential security risks. 279 | 280 | 281 | YANG data models are generally designed to be used with the 282 | NETCONF protocol over an SSH transport. This provides an 283 | authenticated and secure channel over which to transfer 284 | configuration and operational data. Note that use of 285 | alternate transport or data encoding (e.g., JSON over HTTPS) 286 | would require similar mechanisms for authenticating and 287 | securing access to configuration data. 288 | 289 | 290 | 291 | Most of the data elements in the network intsance model could 292 | be considered sensitive from a security standpoint. 293 | Unauthorized access or invalid data could cause major 294 | disruption. 295 | 296 | 297 |
298 | 299 |
300 | 301 | 302 | This YANG data model and the component modules currently use a 303 | temporary ad-hoc namespace. If and when it is placed on 304 | redirected for the standards track, an appropriate namespace URI 305 | will be registered in the IETF XML 306 | Registry". The routing policy YANG modules will be 307 | registered in the "YANG Module Names" registry [RFC6020]. 308 | 309 |
310 | 311 |
312 | 313 | 314 | The network instance model is described by the YANG module 315 | below. 316 | 317 | 318 |
319 | 320 | file openconfig-network-instance.yang 322 | 323 | 324 | ]]> 325 | 326 |
327 | 328 |
329 | file openconfig-network-instance-types.yang 331 | 332 | 333 | ]]> 334 | 335 |
336 |
337 |
338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 350 | 351 | OpenConfig YANG Data Model Repository - 352 | Network Instance 353 | 354 | 355 | 356 | 357 | 358 | 359 |
360 | TODO 361 | 362 |
363 |
364 |
365 | -------------------------------------------------------------------------------- /ietf/drafts/draft-openconfig-rtgwg-network-instance-00.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Data Model for Network Instances in Service Provider Networks 6 | 7 | 8 | 9 | 10 | Routing 11 | 12 | 13 | 14 | This document defines a YANG data model for configuring and 15 | managing forwarding instances on a network device - focused 16 | primarily on deployments in service provider networks. The 17 | model is vendor-neutral and based on operational 18 | requirements expressed by operators. A 'network instance' is 19 | defined to be a discrete forwarding table on a network 20 | element, which contains Layer 3 and/or Layer 2 forwarding 21 | entries. Each network instance may instantiate its own 22 | sets of protocols which control installation of 23 | forwarding entries into one or more tables (which may be 24 | Layer 2 FIBs, or Layer 3 RIBs). 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | Within service provider networks, it is typical for a 33 | network element to maintain multiple forwarding tables, 34 | allowing the network to support multiple topologies. For 35 | instance, a service provider may offer Layer 2 or Layer 3 36 | VPN services to its customers - which requires a forwarding 37 | table per customer to be maintained on a network element. In 38 | other cases, multiple L3 services may be deployed to allow 39 | services such as Internet connectivity and private 40 | topologies to be maintained on a device. 41 | 42 | 43 | This YANG data model defines a 44 | construct which can be used to configure and retrieve 45 | operational state related to such instances. 46 | 47 |
48 | 49 | The concept of maintaining multiple Layer 2 virtual switch 50 | instances (VSIs) and/or multiple Layer 3 virtual routing 51 | and forwarding (VRF) tables is common on network elements 52 | that are deployed in service provider networks. However, 53 | within such networks there are requirements for a network 54 | instance to run both Layer 2 and Layer 3 routing 55 | protocols, or contain routed interfaces (e.g., a VPLS 56 | service where there is a Layer 3 interface within it, for 57 | subscriber termination or to act as a default gateway). 58 | For this reason, the intention of the model presented 59 | here is to define a generic construct which allows 60 | isolation of a forwarding table which may contain Layer 3 61 | RIB entries, Layer 2 FIB entries, or a combination both. 62 | This differs to the approach taken in other models, which 63 | tend to focus on solely L2 VSIs or L3 VRFs. An instance 64 | within the model is referred to as network instance - and 65 | may be configured to support L3 RIB entries only (i.e., be 66 | functionally equivalent to a VRF), L2 FIB entries only 67 | (i.e., act as a VSI) or support a combination of both. 68 | 69 | 70 | The model presented in this document is explicitly biased 71 | towards deployments on service provider network equipment, 72 | as discussed between members of the OpenConfig project. 73 | 74 |
75 |
76 |
77 |
78 | 79 | module: openconfig-network-instance 80 | +--rw network-instances 81 | +--rw network-instance* [name] 82 | +--rw name -> ../config/name 83 | +--rw config 84 | ... 85 | +--ro state 86 | ... 87 | +--rw inter-instance-policies 88 | | +--rw apply-policy 89 | ... 90 | +--rw table-connections 91 | | +--rw table-connection* [src-table dst-table] 92 | | +--rw src-table -> ../config/src-table 93 | | +--rw dst-table -> ../config/dst-table 94 | ... 95 | | +--rw apply-policy 96 | ... 97 | +--rw tables 98 | | +--rw table* [table-name] 99 | ... 100 | +--rw interfaces 101 | .... 102 | +--rw connection-points 103 | | +--rw connection-point* [connection-point-id] 104 | ... 105 | +--rw protocols 106 | +--rw protocol* [identifier name] 107 | ... 108 | +--rw static 109 | ... 110 | +--rw aggregate 111 | ... 112 | 113 |
114 | 115 | The key elements of the network instance model shown in 116 | the above outline tree view are: 117 | 118 | 119 | Type of network instance and key configuration parameters 120 | that relate to it (e.g., configuration of a route 121 | distinguisher for L3 routing instance). 122 | 123 | 124 | Policies which define how the instance exchanges routes 125 | with other instances - for example, allowing forwarding 126 | entries to be leaked between a global and private network 127 | instance. 128 | 129 | 130 | The individual tables that are maintained by a network 131 | instance. This caters for the approach whereby an 132 | implementation maintains per-protocol tables - and it is 133 | possible to examine these tables separately. The choice to 134 | implement this table definition is an open issue - as 135 | discussed in . Along 136 | with this table definition, a set of policies determining 137 | how entries are leaked between the tables is defined. 138 | 139 | 140 | Connections between the different tables that are 141 | maintained by the network instance. Where protocols 142 | populate individual tables, such connections facilitate 143 | leaking of routes between individual protocols (by means 144 | of populating entries from one into the table of the 145 | other). 146 | 147 | 148 | The interfaces associated with a certain network instance 149 | - the current implementation assumption (as demonstrated 150 | in the openconfig-interfaces models) is that configuration 151 | parameters that relate directly to the interface (e.g., 152 | IP addressing) are configured directly under the interface 153 | construct. This requires that a network instance must have 154 | a means to be able to associate itself with an interface. 155 | 156 | 157 | A logical grouping of local or remote interfaces into 158 | 'connection points' utilised by a number of Layer 2 159 | forwarding approaches (e.g., redundancy for attachment 160 | points for PWE or L2VPN services). This allows interfaces 161 | which are associated with the network instance to be 162 | associated with one another, and hence referenced as a 163 | group. This construct can be used to represent redundant 164 | interfaces for a P2P L2VPN - and is extensible to support 165 | Ethernet segments for other L2VPN types. 166 | 167 | 168 | A list of the protocols that are instantiated under the 169 | network instance. The protocols that are defined in are 171 | included directly such that forwarding entries generated 172 | as static or aggregate routes can be matched in a routing 173 | policy. Other protocols, such as BGP (for which the data 174 | model is defined in would augment this list to include their own 176 | configuration options). It should be noted that the list 177 | of protocols is not keyed directly on the protocol name, 178 | but rather also includes an identifier for that instance. 179 | This supports cases where a single network instance may 180 | run multiple instances of a protocol. 181 | 182 | 183 | 184 | 185 | It is expected that all devices maintain at least one network 186 | instance, which represents the default (or global) forwarding 187 | table of the device. Additional instances are intended to 188 | support virtual instances, such as VSIs and VRFs. 189 | 190 | 191 | Where base configuration is required for such instances to be 192 | utilised (e.g., an route distinguisher value is required) then 193 | this is configured globally for each network instance. It 194 | expected that additional parameters, such as the encapsulation 195 | utilised for the instance will be added in future revisions of 196 | the model. 197 | 198 | 199 | Policies for leaking of routes between instances and tables 200 | leverage as a 201 | policy framework. This allows definition of 'import' policies 202 | (allowing a pull model) or export policies (allowing a push 203 | model) to be utilised for installation of entries into a local 204 | or remote network instance. The same framework is utilised to 205 | leak prefixes between multiple tables that are instantiated 206 | under an individual network instance. 207 | 208 |
210 | 211 | Whilst the initial focus of parameters in the 212 | model is to allow the instantiation of attributes related to 213 | Layer 3 forwarding constructs - it is expected that other 214 | configuration parameters, such as the definition of 215 | 'cross-connections' between local and/or remote interfaces 216 | or connection points can be utilised to represent forwarding 217 | constructs within the network instance. 218 | 219 | 220 | The addition of this to the model is still a 221 | work-in-progress. The inclusion of the connection point 222 | configuration and state parameters is intended to 223 | demonstrate how L2 and L3 constructs can co-exist with one 224 | another within the model. 225 | 226 |
227 |
228 |
229 |
231 | 232 | Some implementations maintain a single table into which all 233 | protocols install entries. Each protocol is then configured 234 | to explicitly import entries from that table into their 235 | local 'export' table. Others maintain multiple RIBs and 236 | require explicit connections to be made between these tables 237 | such that entries from one protocol are made available to 238 | another. 239 | 240 | 241 | There are essentially two alternatives for how this is 242 | modelled in the network-instance model: 243 | 244 | 245 | Allow each protocol to specify a 'target-table' that 246 | indicates the table that its entries are to be installed 247 | into. In the case that the same target table is 248 | specified for multiple protocols, implicit import/export 249 | configuration between tables could be created on 250 | implementations that implement multiple RIBs. Explicit 251 | configuration can be utilised to explicitly allow an 252 | operator to leak between tables in the case that 253 | multiple target tables are specified. It should be noted 254 | that in fact, protocols that support multiple address 255 | families need to allow specification of the target table 256 | on a per-address-family basis. 257 | 258 | 259 | Assume that all protocols implement their own target 260 | tables. In this case, explicit configuration is utilised 261 | to leak between them. Implementations that do not 262 | support such per-protocol tables could implicitly 263 | generate the configuration that results in forwarding 264 | entries being leaked between the tables such that the 265 | appearance of a single target-table is maintained. 266 | 267 | 268 | As per the discussion in 269 | currently, this model chooses the former implementation 270 | approach. 271 | 272 |
273 |
274 |
275 | 276 | 277 | Routing configuration has a significant impact on network operations, 278 | and as such any related model carries potential security risks. 279 | 280 | 281 | YANG data models are generally designed to be used with the 282 | NETCONF protocol over an SSH transport. This provides an 283 | authenticated and secure channel over which to transfer 284 | configuration and operational data. Note that use of 285 | alternate transport or data encoding (e.g., JSON over HTTPS) 286 | would require similar mechanisms for authenticating and 287 | securing access to configuration data. 288 | 289 | 290 | 291 | Most of the data elements in the network intsance model could 292 | be considered sensitive from a security standpoint. 293 | Unauthorized access or invalid data could cause major 294 | disruption. 295 | 296 | 297 |
298 | 299 |
300 | 301 | 302 | This YANG data model and the component modules currently use a 303 | temporary ad-hoc namespace. If and when it is placed on 304 | redirected for the standards track, an appropriate namespace URI 305 | will be registered in the IETF XML 306 | Registry". The routing policy YANG modules will be 307 | registered in the "YANG Module Names" registry [RFC6020]. 308 | 309 |
310 | 311 |
312 | 313 | 314 | The network instance model is described by the YANG module 315 | below. 316 | 317 | 318 |
319 | file openconfig-network-instance.yang 321 | 322 | 323 | ]]> 324 | 325 |
326 | 327 |
328 | file openconfig-network-instance-types.yang 330 | 331 | 332 | ]]> 333 | 334 |
335 |
336 |
337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 349 | 350 | OpenConfig YANG Data Model Repository - 351 | Network Instance 352 | 353 | 354 | 355 | 356 | 357 | 358 |
359 | TODO 360 | 361 |
362 |
363 |
364 | -------------------------------------------------------------------------------- /ietf/drafts/draft-shaikh-idr-bgp-model-00.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BGP Configuration Model for Service Provider Networks 6 | 7 | Google 8 |
9 | 10 | 1600 Amphitheatre Pkwy 11 | Mountain View 12 | CA 13 | 94043 14 | US 15 | 16 | aashaikh@google.com 17 |
18 |
19 | 20 | AT&T 21 |
22 | 23 | 200 S. Laurel Ave 24 | Middletown 25 | NJ 26 | US 27 | 28 | kd6913@att.com 29 |
30 |
31 | 67 | 68 | Microsoft 69 |
70 | 71 | 205 108th Ave. NE, Suite 400 72 | Bellevue 73 | WA 74 | US 75 | 76 | dbansal@microsoft.com 77 |
78 |
79 | 80 | BT 81 |
82 | 83 | pp. C3L, BT Centre 84 | 81, Newgate Street 85 | London 86 | EC1A 7AJ 87 | UK 88 | 89 | rob.shakir@bt.com 90 | http://www.bt.com/ 91 |
92 |
93 | 94 | 95 | 96 | Routing 97 | 98 | 99 | This document defines a YANG data model for configuring and 100 | managing BGP, including protocol, policy, and operational 101 | aspects based on carrier and content provider operational 102 | requirements. 103 | 104 | 105 |
106 | 107 | 108 |
109 | This document describes a YANG 110 | data model for BGP protocol and policy 111 | configuration, as well as defining key operational state data. 112 | The model is intended to be vendor-neutral, in order to allow 113 | operators to manage BGP configuration in heterogeneous 114 | environments with routers supplied by multiple vendors. The 115 | model is also intended to be readily mapped to existing 116 | implementations, however, to facilitate support from as large a 117 | set of routing hardware and software vendors as possible. 118 | 119 |
120 | This model does not (in the current iteration) aim to be 121 | feature complete (i.e., cover all possible features of a BGP 122 | implementation). Rather its development is driven by 123 | examination of BGP configurations in use across a number of 124 | operator network deployments. 125 | 126 | 127 | The focus area of the first version of the model is on base 128 | BGP protocol configuration and policy configuration with 129 | "hooks" to add support for additional address families, as well 130 | as operational data to enable a common model for reading 131 | BGP-related state from devices. 132 | 133 | 134 | Configuration items that are deemed to be widely available 135 | in existing major BGP implementations are included in the 136 | model. Those configuration items that are only available from 137 | a single implementation are omitted from the model with the 138 | expectation they will be available in companion modules that 139 | augment the current model. This allows clarity in identifying 140 | data that is part of the vendor-neutral model. 141 | 142 | 143 | Where possible, naming in the model follows conventions 144 | used in available standards documents, and otherwise tries to 145 | be self-explanatory with sufficient descriptions of the 146 | intended behavior. Similarly, configuration data value 147 | constraints and default values, where used, are based on 148 | recommendations in current standards documentation. Since 149 | implementations vary widely in this respect, this version of 150 | the model specifies only a limited set of defaults and ranges 151 | with the expectation of being more prescriptive in future 152 | versions based on actual operator use. 153 | 154 |
155 |
156 | 157 |
158 | The BGP model is defined across several YANG modules but at a 159 | high level is organized into three main parts: 160 | 161 | 162 | 163 | protocol configuration -- configuration affecting BGP 164 | protocol-related operations, defined at various levels 165 | of hierarchy. 166 | 167 | policy configuration -- configuration defining the 168 | policies that act on routes sent (received) to (from) 169 | peers or other routing protocols. 170 | 171 | operational state -- variables used for monitoring, 172 | management, etc. of BGP operations. 173 | 174 | 175 | 176 | 177 | These modules also make use of the standard Internet types, such as IP addresses, autonomous system numbers, etc., defined in RFC 6991. 178 | 179 |
181 | The BGP protocol configuration model is organized 182 | hierarchically, much like the majority of router 183 | implementations. That is, configuration items can be 184 | specified at multiple levels, as shown below. 185 | 186 |
187 | 188 | +--rw bgp 189 | +--rw global 190 | +--rw afi* [afi-name] 191 | +--rw peer-group* [group-name] 192 | +--rw neighbor* [neighbor-address] 193 | +--rw policy 194 | 195 |
196 | Users may specify configuration at a higher level and 197 | have it apply to all lower-level items, or provide 198 | overriding configuration at a lower level of the 199 | hierarchy. Overriding configuration items are optional. 200 | 201 | The model makes the simplifying assumption that most of 202 | the configuration items are available at all levels of the 203 | hierarchy. That is, very little configuration is specific 204 | to a particular level in the hierarchy, other than obvious 205 | items such as "group- name" only being available for the 206 | peer group-level config. A notable exception is for 207 | sub-address family configuration where some items are only 208 | applicable for a given AFI-SAFI combination. 209 | 210 | The initial version of the model includes placeholders 211 | (i.e., mount points) for configuring different address 212 | family or sub address family (AFI/SAFI) combinations in 213 | support of BGP multiprotocol 214 | extensions. The focus, however, is on base IPv4 and 215 | IPv6 configuration, with later versions of the model 216 | providing additional configuration for specific AFI/SAFI 217 | types. The current scope of AFI/SAFI combinations is 218 | indicated below. Each of the subtrees are containers for 219 | configuration specific to the corresponding AFI-SAFI 220 | combination. 221 | 222 |
223 | 224 | +--rw bgp 225 | +--rw afi* [afi-name] 226 | +--rw safi* [safi-name] 227 | +--rw safi-name identityref 228 | +--rw ipv4-ipv6-unicast 229 | +--rw ipv4-l3vpn-unicast 230 | +--rw ipv6-l3vpn-unicast 231 | +--rw ipv4-labeled-unicast 232 | +--rw l2vpn 233 | +--rw ipv4-multicast-vpn 234 | +--rw ipv6-multicast-vpn 235 | +--rw prefix-limit 236 | +--rw apply-policy 237 | 238 |
239 | 240 |
241 | 242 |
244 | The BGP policy configuration model is based on a 245 | condition-action model in which policies are expressed as 246 | a series of conditions, each with a corresponding action. 247 | Conditions include testing for membership in a predefined 248 | set (e.g., community attribute matches a predefined set 249 | of communities), or testing route attributes for specified 250 | values. Actions support setting specific attributes on a 251 | route or performing a control flow operation such as 252 | accepting or rejecting a route, or going to the next 253 | policy. 254 | 255 | The general structure of policy definitions, policy 256 | statements, and condition-action policy rules is shown 257 | below. 258 | 259 |
260 | 261 | +--rw bgp 262 | +--rw policy 263 | +--rw policy-definitions! 264 | +--rw policy-definition* [name] 265 | +--rw name string 266 | +--rw statements* [name] 267 | +--rw name string 268 | +--rw conditions 269 | +--rw actions 270 | 271 |
272 | The policy model supports policy subroutines 273 | through the use of the condition statement call-policy which 274 | applies the conditions from another named policy 275 | definition. It also supports policy chaining using the 276 | action statements goto-next and goto-policy, which allow 277 | policy evaluation to immediately move to the next policy 278 | statement in the current policy definition, or move to 279 | another named policy definition, respectively. Using 280 | multiple policy statements in a policy definition is also a 281 | form of policy chaining which will evaluate each policy 282 | statement in turn. 283 | 284 | 285 |
286 |
288 | The BGP operational data model contains an initial set of 289 | state variable definitions that would be required in most 290 | service provider deployments for management, monitoring, and 291 | fault detection. 292 | 293 |
294 |
295 | 296 |
297 | 298 | BGP configuration has a significant impact on network operations, 299 | and as such any related protocol or model carries potential 300 | security risks. 301 | 302 | 303 | YANG data models are generally designed to be used with the 304 | NETCONF protocol over an SSH transport. This provides an 305 | authenticated and secure channel over which to transfer BGP 306 | configuration and operational data. Note that use of 307 | alternate transport or data encoding (e.g., JSON over HTTPS) 308 | would require similar mechanisms for authenticating and 309 | securing access to configuration data. 310 | 311 | 312 | Most of the data elements in the configuration model could be 313 | considered sensitive from a security standpoint. Unauthorized 314 | access or invalid data could cause major disruption. 315 | 316 | 317 |
318 | 319 |
320 | 321 | This YANG data model and the component modules currently use 322 | a temporary ad-hoc namespace. If and when it is placed on redirected for 323 | the standards track, an appropriate namespace URI will be 324 | registered in the IETF XML Registry". The BGP YANG 325 | modules will be registered in the "YANG Module Names" registry 326 | [RFC6020]. 327 | 328 |
329 | 330 |
331 | 332 | The modules comprising the BGP configuration and 333 | operational model are described by the YANG modules in the 334 | sections below. The base module imports the other modules to 335 | create the overall model. 336 | 337 | 338 |
339 |
340 | file bgp.yang 342 | 343 | 344 | ]]> 345 | 346 |
347 |
348 | 349 |
350 |
351 | file bgp-policy.yang 353 | 354 | 355 | ]]> 356 | 357 |
358 |
359 | 360 |
361 |
362 | file bgp-multiprotocol.yang 364 | 365 | 366 | ]]> 367 | 368 |
369 |
370 | 371 |
372 |
373 | file bgp-operational.yang 375 | 376 | 377 | ]]> 378 | 379 |
380 |
381 | 382 |
383 | 384 |
385 | 386 | 387 | 388 | 389 | 390 | YANG - A Data Modeling Language for 391 | the Network Configuration Protocol (NETCONF) 392 | 394 | Tail-f Systems 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | A Border Gateway Protocol 4 (BGP-4) 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | Multiprotocol Extensions for BGP-4 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | Common YANG Data Types 439 | 440 | Jacobs University 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | The IETF XML Registry 449 | 451 | Verisign, Inc. 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 |
460 | The authors are grateful for valuable contributions to this 461 | document and the associated models from: Chris Chase, Ed Crabbe, 462 | Josh George, Vijay Gill, Ina Minei, Ashok Narayanan, Steve 463 | Padgett, Puneet Sood, and Jim Uttaro. 464 | 465 | 468 |
469 |
470 |
471 | -------------------------------------------------------------------------------- /ietf/drafts/draft-openconfig-rtgwg-gnmi-spec-01.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Network Working Group R. Shakir 6 | Internet-Draft A. Shaikh 7 | Intended status: Informational P. Borman 8 | Expires: September 6, 2018 M. Hines 9 | C. Lebsack 10 | C. Morrow 11 | Google 12 | March 5, 2018 13 | 14 | 15 | gRPC Network Management Interface (gNMI) 16 | draft-openconfig-rtgwg-gnmi-spec-01 17 | 18 | Abstract 19 | 20 | This document describes the gRPC Network Management Interface (gNMI), 21 | a network management protocol based on the gRPC framework. gNMI 22 | supports retrieval and manipulation of state from network elements 23 | where the data is represented by a tree structure, and addressable by 24 | paths. The gNMI service defines operations for configuration 25 | management, operational state retrieval, and bulk data collection via 26 | streaming telemetry. The authoritative gNMI specification is 27 | maintained at [GNMI-SPEC]. 28 | 29 | Status of This Memo 30 | 31 | This Internet-Draft is submitted in full conformance with the 32 | provisions of BCP 78 and BCP 79. 33 | 34 | Internet-Drafts are working documents of the Internet Engineering 35 | Task Force (IETF). Note that other groups may also distribute 36 | working documents as Internet-Drafts. The list of current Internet- 37 | Drafts is at http://datatracker.ietf.org/drafts/current/. 38 | 39 | Internet-Drafts are draft documents valid for a maximum of six months 40 | and may be updated, replaced, or obsoleted by other documents at any 41 | time. It is inappropriate to use Internet-Drafts as reference 42 | material or to cite them other than as "work in progress." 43 | 44 | This Internet-Draft will expire on September 6, 2018. 45 | 46 | Copyright Notice 47 | 48 | Copyright (c) 2018 IETF Trust and the persons identified as the 49 | document authors. All rights reserved. 50 | 51 | This document is subject to BCP 78 and the IETF Trust's Legal 52 | Provisions Relating to IETF Documents 53 | 54 | 55 | 56 | Shakir, et al. Expires September 6, 2018 [Page 1] 57 | 58 | Internet-Draft gNMI specification March 2018 59 | 60 | 61 | (http://trustee.ietf.org/license-info) in effect on the date of 62 | publication of this document. Please review these documents 63 | carefully, as they describe your rights and restrictions with respect 64 | to this document. Code Components extracted from this document must 65 | include Simplified BSD License text as described in Section 4.e of 66 | the Trust Legal Provisions and are provided without warranty as 67 | described in the Simplified BSD License. 68 | 69 | Table of Contents 70 | 71 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 72 | 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 73 | 3. Protocol overview . . . . . . . . . . . . . . . . . . . . . . 3 74 | 3.1. Data payloads and paths . . . . . . . . . . . . . . . . . 3 75 | 3.2. gNMI RPCs . . . . . . . . . . . . . . . . . . . . . . . . 4 76 | 3.2.1. Capabilities . . . . . . . . . . . . . . . . . . . . 4 77 | 3.2.2. Subscribe . . . . . . . . . . . . . . . . . . . . . . 5 78 | 3.2.3. Set . . . . . . . . . . . . . . . . . . . . . . . . . 5 79 | 3.2.4. Get . . . . . . . . . . . . . . . . . . . . . . . . . 5 80 | 4. Additional operations . . . . . . . . . . . . . . . . . . . . 5 81 | 4.1. Error handling . . . . . . . . . . . . . . . . . . . . . 6 82 | 4.2. gNMI Extensions . . . . . . . . . . . . . . . . . . . . . 6 83 | 5. Security Considerations . . . . . . . . . . . . . . . . . . . 6 84 | 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 6 85 | 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 6 86 | 7.1. Normative references . . . . . . . . . . . . . . . . . . 6 87 | 7.2. Informative references . . . . . . . . . . . . . . . . . 6 88 | Appendix A. Change summary . . . . . . . . . . . . . . . . . . . 7 89 | A.1. Changes between revisions -00 and -01 . . . . . . . . . . 7 90 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 8 91 | 92 | 1. Introduction 93 | 94 | This document provides an overview of gNMI, a gRPC-based protocol for 95 | state management on network elements [GRPC].The gRPC Network 96 | Management Interface (gNMI) supports modification and retrieval of 97 | configuration, as well as control and transmission telemetry streams 98 | from a network element to a data collection system.This allows a 99 | single implementation on the network element, as well as a single NMS 100 | element to interact with the device via telemetry and configuration 101 | RPCs. 102 | 103 | All messages within the gRPC service definition are defined as 104 | protocol buffers (specifically proto3) [PROTO].gRPC service 105 | definitions are described using the relevant features of the protobuf 106 | IDL.The authoritative protobuf definition is maintained in 107 | [GNMI-PROTO].The current, authoritative version of the gNMI 108 | specification is available at [GNMI-SPEC]. 109 | 110 | 111 | 112 | Shakir, et al. Expires September 6, 2018 [Page 2] 113 | 114 | Internet-Draft gNMI specification March 2018 115 | 116 | 117 | gNMI offers an alternative to management protocols such as NETCONF 118 | [RFC6241] and RESTCONF [RFC8040] with implementations on devices from 119 | multiple vendors.gNMI derives a number of benefits from being built 120 | on gRPC and HTTP/2, including modern security mechanisms, 121 | bidirectional streaming, binary framing, and a wide variety of 122 | language bindings to simplify integration with management 123 | applications.With protobuf encoding, it also provides significant 124 | efficiency advantages over XML serialization with a 3 to 10 times 125 | reduction in data volume (see the "Developer Guide" in [PROTO] for 126 | examples).A number of open source tools and reference implementations 127 | are available from the OpenConfig working group [GNMI-TOOLS]. 128 | 129 | 2. Terminology 130 | 131 | Throughout this document the following terminology is used: 132 | 133 | o Telemetry - refers to streaming data relating to underlying 134 | characteristics of the device - either operational state or 135 | configuration. 136 | 137 | o Configuration - elements within the data schema which are read/ 138 | write and can be manipulated by the client. 139 | 140 | o Target - the device within gNMI which acts as the owner of the 141 | data that is being manipulated or reported on. Typically this 142 | will be a network device. 143 | 144 | o Client - the device or system using gNMI to query/modify data on 145 | the target, or act as a collector for telemetry data. Typically 146 | this will be a network management application. 147 | 148 | 3. Protocol overview 149 | 150 | The sections below provide an overview of the gNMI protocol 151 | operations, leaving a detailed discussion to the full specification 152 | in [GNMI-SPEC]. 153 | 154 | 3.1. Data payloads and paths 155 | 156 | gNMI is often used to carry payloads that contain data instances of 157 | YANG schemas (for example based on OpenConfig models [OPENCONFIG]), 158 | but can be used for any data with the following characteristics: 159 | 160 | 1. structure that can be represented by a tree, where nodes can be 161 | uniquely identified by a path consisting of node names, or node 162 | names coupled with attributes; 163 | 164 | 2. values can be serialised into a scalar object. 165 | 166 | 167 | 168 | Shakir, et al. Expires September 6, 2018 [Page 3] 169 | 170 | Internet-Draft gNMI specification March 2018 171 | 172 | 173 | Values may be serialised to native protobuf scalar types, structured 174 | data types (e.g. as JSON or protobuf object), or a schema language- 175 | specific type (e.g., YANG Decimal64). 176 | 177 | Data in gNMI is addressed by a path, which is represented as a 178 | structured list of elements, each with associated attributes if 179 | present. For example, the human-readable path 180 | "/interfaces/interface[name=eth0]/config/description" is represented 181 | as a text-encoded protobuf as: 182 | 183 | path: < 184 | elem: < 185 | name: "interfaces" 186 | > 187 | elem: < 188 | name: "interface" 189 | key: < 190 | key: "name" 191 | value: "eth0" 192 | > 193 | > 194 | elem: < 195 | name: "config" 196 | > 197 | elem: < 198 | name: "description" 199 | > 200 | > 201 | 202 | For more efficient handling of paths, gNMI supports a path prefix 203 | that is applied to every path in a message. Paths in gNMI are always 204 | absolute, constructed by concatenating the prefix with the path. 205 | 206 | 3.2. gNMI RPCs 207 | 208 | gNMI is designed with a small number of base remote procedure calls 209 | (RPCs) to simplify client and target implementations. This section 210 | provides a high-level overview of each RPC. Full details are 211 | available in [GNMI-SPEC]. 212 | 213 | 3.2.1. Capabilities 214 | 215 | The Capabilities RPC allows a client to interrogate a gNMI target to 216 | learn about supported features. The primary information returned by 217 | a target include the set of models it supports, the data encodings 218 | supported, and the version of the gNMI protocol it is using. The 219 | model information is expected to be based on a published model 220 | catalog [I-D.openconfig-netmod-model-catalog]. 221 | 222 | 223 | 224 | Shakir, et al. Expires September 6, 2018 [Page 4] 225 | 226 | Internet-Draft gNMI specification March 2018 227 | 228 | 229 | 3.2.2. Subscribe 230 | 231 | Subscribe is a bidirectional streaming RPC that allows clients and 232 | targets to send independent sequences of telemetry messages. Clients 233 | may subscribe to notifications for telemetry data by specifying a 234 | path to the desired data and a mode (in addition to other 235 | parameters). gNMI supports several modes, but the two common use 236 | cases are for periodically sampled data, such as counters, and event- 237 | driven data in which a notification is sent only when the 238 | corresponding data value changes. In response to a subscription, the 239 | target sends a stream of telemetry notifications that contain a 240 | timestamp, path, and updated value. Multiple updates may be included 241 | in a single RPC message. 242 | 243 | A streaming RPC for telemetry has the benefit of not requiring the 244 | target to collect, stage in memory, and serialize all of the 245 | requested data at once. The target is able to send data as soon as 246 | it is available, and can manage its resources to avoid becoming 247 | overloaded when sending a large volume of data. 248 | 249 | 3.2.3. Set 250 | 251 | Set is a unary RPC (i.e., single request and single response) that is 252 | sent by a client to update the state of the target. Set includes 253 | several operation types whereby data may be updated, deleted, or 254 | replaced. A Set RPC may include multiple operations -- the target is 255 | expected to treat each RPC as a transaction such that if all included 256 | operations cannot be completed successfully, the target's state is 257 | unchanged. Clients using the gNMI Set RPC pre-stage a set of update 258 | operations into a single Set RPC call, which must be either 259 | completely applied, or rolled back - eliminating the complex, long- 260 | lived candidate changes used in other protocols. 261 | 262 | 3.2.4. Get 263 | 264 | Get is also a unary RPC that allows clients to request an immediate 265 | snapshot of the current state from the target, specified by a path. 266 | The target is expected to collect the data when the request is 267 | received, and serialize it for immediate transmission to the client. 268 | Where supported, gNMI allows the client to specify the type of data 269 | that should be returned (e.g., configuration state, operational 270 | state, etc.). 271 | 272 | 4. Additional operations 273 | 274 | The sections below describe additional features and operations in 275 | gNMI. 276 | 277 | 278 | 279 | 280 | Shakir, et al. Expires September 6, 2018 [Page 5] 281 | 282 | Internet-Draft gNMI specification March 2018 283 | 284 | 285 | 4.1. Error handling 286 | 287 | Rather than defining application-level error messates, gNMI leverages 288 | native error handling mechanisms in gRPC in which canonical error 289 | codes and context information are part of the Status message in every 290 | RPC. The gNMI specification provides guidance on how gNMI error 291 | conditions should be mapped to canonical error codes. 292 | 293 | 4.2. gNMI Extensions 294 | 295 | While the base gNMI protocol is deliberately limited to a set of 296 | simple operations, some use cases require additional parameters that 297 | may be only applicable in those scenarios. gNMI extensions 298 | [GNMI-EXT] define a common way to add new payload to gNMI RPCs for 299 | these use cases without requiring changes in the core protocol 300 | specification. 301 | 302 | 5. Security Considerations 303 | 304 | gNMI allows access and manipulation of state on network devices, 305 | hence it requires careful consideration of security implications 306 | including authentication and authorization of RPCs. The gNMI 307 | specification [GNMI-SPEC] and companion document [GNMI-SECURITY] 308 | discuss the considerations in more detail. 309 | 310 | 6. IANA Considerations 311 | 312 | No IANA considerations at this time. In the future there may be a 313 | request for a protocol registry entry and well-known port allocation. 314 | 315 | 7. References 316 | 317 | 7.1. Normative references 318 | 319 | [RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., 320 | and A. Bierman, Ed., "Network Configuration Protocol 321 | (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011, 322 | . 323 | 324 | [RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF 325 | Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017, 326 | . 327 | 328 | 7.2. Informative references 329 | 330 | [GRPC] The gRPC authors, "gRPC", March 2018, . 331 | 332 | 333 | 334 | 335 | 336 | Shakir, et al. Expires September 6, 2018 [Page 6] 337 | 338 | Internet-Draft gNMI specification March 2018 339 | 340 | 341 | [PROTO] Google, "Protocol buffers", March 2018, 342 | . 343 | 344 | [GNMI-PROTO] 345 | OpenConfig operator working group, "gnmi.proto", February 346 | 2018, 347 | . 349 | 350 | [GNMI-SPEC] 351 | OpenConfig operator working group, "gRPC Network 352 | Management Interface (gNMI) v0.6.0", January 2018, 353 | . 355 | 356 | [GNMI-TOOLS] 357 | OpenConfig operator working group, "gNMI Github 358 | repository", March 2018, . 360 | 361 | [GNMI-EXT] 362 | OpenConfig operator working group, "Extensions to gNMI", 363 | January 2018, 364 | . 366 | 367 | [GNMI-SECURITY] 368 | OpenConfig operator working group, "gNMI Authentication 369 | and Encryption", October 2016, 370 | . 372 | 373 | [OPENCONFIG] 374 | OpenConfig operator working group, "OpenConfig", March 375 | 2018, . 376 | 377 | [I-D.openconfig-netmod-model-catalog] 378 | Shaikh, A., Shakir, R., and K. D'Souza, "Catalog and 379 | registry for YANG models", draft-openconfig-netmod-model- 380 | catalog-02 (work in progress), March 2017. 381 | 382 | Appendix A. Change summary 383 | 384 | A.1. Changes between revisions -00 and -01 385 | 386 | o Replaced specification content with overview material and 387 | reference to normative reference to the gNMI specification 388 | document 389 | 390 | 391 | 392 | Shakir, et al. Expires September 6, 2018 [Page 7] 393 | 394 | Internet-Draft gNMI specification March 2018 395 | 396 | 397 | o Updated to reflect changes in the gNMI specification and 398 | introduction of gNMI extensions. 399 | 400 | Authors' Addresses 401 | 402 | Rob Shakir 403 | Google, Inc. 404 | 1600 Amphitheatre Parkway 405 | Mountain View, CA 94043 406 | 407 | Email: robjs@google.com 408 | 409 | 410 | Anees Shaikh 411 | Google 412 | 1600 Amphitheatre Pkwy 413 | Mountain View, CA 94043 414 | US 415 | 416 | Email: aashaikh@google.com 417 | 418 | 419 | Paul Borman 420 | Google 421 | 1600 Amphitheatre Pkwy 422 | Mountain View, CA 94043 423 | US 424 | 425 | Email: borman@google.com 426 | 427 | 428 | Marcus Hines 429 | Google 430 | 1600 Amphitheatre Pkwy 431 | Mountain View, CA 94043 432 | US 433 | 434 | Email: hines@google.com 435 | 436 | 437 | Carl Lebsack 438 | Google 439 | 1600 Amphitheatre Pkwy 440 | Mountain View, CA 94043 441 | US 442 | 443 | Email: csl@google.com 444 | 445 | 446 | 447 | 448 | Shakir, et al. Expires September 6, 2018 [Page 8] 449 | 450 | Internet-Draft gNMI specification March 2018 451 | 452 | 453 | Chris Morrow 454 | Google 455 | 456 | Email: christopher.morrow@gmail.com 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | Shakir, et al. Expires September 6, 2018 [Page 9] 505 | --------------------------------------------------------------------------------