diff --git a/Makefile b/Makefile index a873a0c93..21fca954b 100644 --- a/Makefile +++ b/Makefile @@ -9,11 +9,19 @@ test: generate: cd ${ROOT_DIR}/demo/getting_started && go generate cd ${ROOT_DIR}/proto/ywrapper && go generate + cd $(ROOT_DIR)/proto/yext && go generate cd $(ROOT_DIR)/demo/uncompressed && go generate + cd $(ROOT_DIR)/demo/protobuf_getting_started && ./update.sh clean: rm -f ${ROOT_DIR}/demo/getting_started/pkg/ocdemo/oc.go rm -f ${ROOT_DIR}/demo/uncompressed/pkg/demo/uncompressed.go deps: - go get -t -d ./... + go get -t -d ./ygot + go get -t -d ./ygen + go get -t -d ./generator + go get -t -d ./proto_generator + go get -t -d ./exampleoc + go get -t -d ./ytypes + go get -t -d ./demo/gnmi_telemetry install: deps generate all: clean deps generate test diff --git a/demo/protobuf_getting_started/.gitignore b/demo/protobuf_getting_started/.gitignore new file mode 100644 index 000000000..ce3ef691f --- /dev/null +++ b/demo/protobuf_getting_started/.gitignore @@ -0,0 +1,2 @@ +ribproto + diff --git a/demo/protobuf_getting_started/demo.go b/demo/protobuf_getting_started/demo.go new file mode 100644 index 000000000..c2a344c09 --- /dev/null +++ b/demo/protobuf_getting_started/demo.go @@ -0,0 +1,124 @@ +// +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Package main contains a demo of using a protobuf schema generated by ygot +// to generate a Protobuf form of the OpenConfig RIB model. + +package main + +import ( + "fmt" + + log "github.com/golang/glog" + "github.com/golang/protobuf/proto" + + ocpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig" + ocenums "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/enums" + ocrpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp" + ocrbpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib" + ocrbapb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/afi_safis" + ocrbaapb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/afi_safis/afi_safi" + ocrbaai4pb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/afi_safis/afi_safi/ipv4_unicast" + ocrbaai4lpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/afi_safis/afi_safi/ipv4_unicast/loc_rib" + ocrbaai4lrpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/afi_safis/afi_safi/ipv4_unicast/loc_rib/routes" + ocrbaai4lrrpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/afi_safis/afi_safi/ipv4_unicast/loc_rib/routes/route" + ocrapb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/attr_sets" + ocraapb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/openconfig_rib_bgp/bgp_rib/attr_sets/attr_set" + ywpb "github.com/openconfig/ygot/proto/ywrapper" +) + +func main() { + rt := buildRouteProto(&ipv4Prefix{ + atomicAggregate: true, + localPref: 100, + med: 10, + nextHop: "10.0.1.1", + origin: ocenums.OpenconfigRibBgpBgpOriginAttrType_OPENCONFIGRIBBGPBGPORIGINATTRTYPE_EGP, + originatorID: "192.0.2.42", + prefix: "192.0.2.0/24", + protocolOrigin: ocenums.OpenconfigPolicyTypesINSTALLPROTOCOLTYPE_OPENCONFIGPOLICYTYPESINSTALLPROTOCOLTYPE_BGP, + }) + + b, err := proto.Marshal(rt) + if err != nil { + log.Exitf("Error marshalling proto: %v", err) + } + + fmt.Printf("%s\n", proto.MarshalTextString(rt)) + fmt.Printf("Marshalled proto size in bytes: %d\n", len(b)) +} + +// ipv4Prefix describes an IPv4 Prefix within the OpenConfig BGP RIB model. +type ipv4Prefix struct { + atomicAggregate bool // atomicAggregate is set when a downstream BGP speaker has aggregated the prefix. + localPref uint64 // localPrefix is the value of the BGP LOCAL_PREFERENCE attribute. + med uint64 // med is the value of the BGP multi-exit discriminator. + nextHop string // nextHop is the IP next-hop used for the BGP route. + origin ocenums.OpenconfigRibBgpBgpOriginAttrType // origin is the value of the ORIGIN attribute of the BGP prefix. + originatorID string // originatorID specifies the address of the BGP originator of the prefix. + prefix string // prefix is the IPv4 prefix for the route. + protocolOrigin ocenums.OpenconfigPolicyTypesINSTALLPROTOCOLTYPE // protocolOrigin specifies the route on the device via which the prefix was learnt. +} + +// buildRouteProto returns a Protobuf representation a route and associated +// attribute set in the OpenConfig BGP RIB model. +func buildRouteProto(pfx *ipv4Prefix) *ocpb.Device { + return &ocpb.Device{ + BgpRib: &ocrpb.BgpRib{ + AttrSets: &ocrbpb.AttrSets{ + AttrSet: []*ocrbpb.AttrSetKey{{ + Index: 1, + AttrSet: &ocrapb.AttrSet{ + State: &ocraapb.State{ + AtomicAggregate: &ywpb.BoolValue{pfx.atomicAggregate}, + Index: &ywpb.UintValue{1}, + LocalPref: &ywpb.UintValue{pfx.localPref}, + Med: &ywpb.UintValue{pfx.med}, + NextHop: &ywpb.StringValue{pfx.nextHop}, + Origin: pfx.origin, + OriginatorId: &ywpb.StringValue{pfx.originatorID}, + }, + }, + }}, + }, + AfiSafis: &ocrbpb.AfiSafis{ + AfiSafi: []*ocrbpb.AfiSafiKey{{ + AfiSafiName: ocenums.OpenconfigBgpTypesAFISAFITYPE_OPENCONFIGBGPTYPESAFISAFITYPE_IPV4_UNICAST, + AfiSafi: &ocrbapb.AfiSafi{ + Ipv4Unicast: &ocrbaapb.Ipv4Unicast{ + LocRib: &ocrbaai4pb.LocRib{ + Routes: &ocrbaai4lpb.Routes{ + Route: []*ocrbaai4lpb.RouteKey{{ + Prefix: pfx.prefix, + Origin: &ocrbaai4lpb.RouteKey_OriginOpenconfigpolicytypesinstallprotocoltype{ocenums.OpenconfigPolicyTypesINSTALLPROTOCOLTYPE_OPENCONFIGPOLICYTYPESINSTALLPROTOCOLTYPE_BGP}, + PathId: 1, + Route: &ocrbaai4lrpb.Route{ + State: &ocrbaai4lrrpb.State{ + PathId: &ywpb.UintValue{1}, + Prefix: &ywpb.StringValue{pfx.prefix}, + Origin: &ocrbaai4lrrpb.State_OriginOpenconfigpolicytypesinstallprotocoltype{pfx.protocolOrigin}, + AttrIndex: &ywpb.UintValue{1}, + }, + }, + }}, + }, + }, + }, + }, + }}, + }, + }, + } +} diff --git a/demo/protobuf_getting_started/demo_test.go b/demo/protobuf_getting_started/demo_test.go new file mode 100644 index 000000000..dd4c00d74 --- /dev/null +++ b/demo/protobuf_getting_started/demo_test.go @@ -0,0 +1,70 @@ +// +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "io/ioutil" + "path/filepath" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/kylelemons/godebug/pretty" + + ocpb "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig" + ocenums "github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto/openconfig/enums" +) + +func TestProtoGenerate(t *testing.T) { + tests := []struct { + name string + inTestFunc func(*ipv4Prefix) *ocpb.Device + inPrefix *ipv4Prefix + wantTextProto string + }{{ + name: "simple route entry test", + inTestFunc: buildRouteProto, + inPrefix: &ipv4Prefix{ + atomicAggregate: true, + localPref: 100, + med: 10, + nextHop: "10.0.1.1", + origin: ocenums.OpenconfigRibBgpBgpOriginAttrType_OPENCONFIGRIBBGPBGPORIGINATTRTYPE_EGP, + originatorID: "192.0.2.42", + prefix: "192.0.2.0/24", + protocolOrigin: ocenums.OpenconfigPolicyTypesINSTALLPROTOCOLTYPE_OPENCONFIGPOLICYTYPESINSTALLPROTOCOLTYPE_BGP, + }, + wantTextProto: "route_entry.txtpb", + }} + + for _, tt := range tests { + got := tt.inTestFunc(tt.inPrefix) + + want := &ocpb.Device{} + + wantStr, err := ioutil.ReadFile(filepath.Join("testdata", tt.wantTextProto)) + if err != nil { + t.Errorf("%s: ioutil.ReadFile(testdata/%s): could not read file, got: %v, want: nil", tt.name, tt.wantTextProto, err) + } + + if err := proto.UnmarshalText(string(wantStr), want); err != nil { + t.Errorf("%s: proto.UnmarshalText(file: %s): could not unmarshal test proto, got: %v, want: nil", tt.name, tt.wantTextProto, err) + } + + if !proto.Equal(got, want) { + t.Errorf("%s: %T: did not get expected return proto, diff(-got,+want):\n%s", tt.name, tt.inTestFunc, pretty.Compare(got, want)) + } + } +} diff --git a/demo/protobuf_getting_started/testdata/route_entry.txtpb b/demo/protobuf_getting_started/testdata/route_entry.txtpb new file mode 100644 index 000000000..05c22f7f9 --- /dev/null +++ b/demo/protobuf_getting_started/testdata/route_entry.txtpb @@ -0,0 +1,62 @@ +bgp_rib: < + afi_safis: < + afi_safi: < + afi_safi_name: OPENCONFIGBGPTYPESAFISAFITYPE_IPV4_UNICAST + afi_safi: < + ipv4_unicast: < + loc_rib: < + routes: < + route: < + prefix: "192.0.2.0/24" + origin_openconfigpolicytypesinstallprotocoltype: OPENCONFIGPOLICYTYPESINSTALLPROTOCOLTYPE_BGP + path_id: 1 + route: < + state: < + attr_index: < + value: 1 + > + origin_openconfigpolicytypesinstallprotocoltype: OPENCONFIGPOLICYTYPESINSTALLPROTOCOLTYPE_BGP + path_id: < + value: 1 + > + prefix: < + value: "192.0.2.0/24" + > + > + > + > + > + > + > + > + > + > + attr_sets: < + attr_set: < + index: 1 + attr_set: < + state: < + atomic_aggregate: < + value: true + > + index: < + value: 1 + > + local_pref: < + value: 100 + > + med: < + value: 10 + > + next_hop: < + value: "10.0.1.1" + > + origin: OPENCONFIGRIBBGPBGPORIGINATTRTYPE_EGP + originator_id: < + value: "192.0.2.42" + > + > + > + > + > +> diff --git a/demo/protobuf_getting_started/update.sh b/demo/protobuf_getting_started/update.sh new file mode 100755 index 000000000..cb56ae59a --- /dev/null +++ b/demo/protobuf_getting_started/update.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +clean() { + rm -rf public + rm -rf deps +} + +# Ensure that the .pb.go has been generated for the extensions +# that are required. +(cd ../../proto/yext && go generate) +(cd ../../proto/ywrapper && go generate) + +clean +rm -rf ribproto + +go run ../../proto_generator/protogenerator.go \ + -generate_fakeroot \ + -base_import_path="github.com/openconfig/ygot/demo/protobuf_getting_started/ribproto" \ + -path=yang -output_dir=ribproto \ + -enum_package_name=enums -package_name=openconfig \ + -exclude_modules=ietf-interfaces \ + yang/rib/openconfig-rib-bgp.yang + +go get -u github.com/google/protobuf +proto_imports=".:${GOPATH}/src/github.com/google/protobuf/src:${GOPATH}/src" +find ribproto -name "*.proto" | while read l; do + protoc -I=$proto_imports --go_out=. $l +done + +clean diff --git a/demo/protobuf_getting_started/yang/deps/ietf-inet-types.yang b/demo/protobuf_getting_started/yang/deps/ietf-inet-types.yang new file mode 100644 index 000000000..08fb3b536 --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/ietf-inet-types.yang @@ -0,0 +1,400 @@ +module ietf-inet-types { + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + contact + "WG Web: + WG List: + WG Chair: David Kessens + + WG Chair: Juergen Schoenwaelder + + Editor: Juergen Schoenwaelder + "; + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + revision 2013-07-15 { + description + "This revision adds the following new data types: + - ip-address-no-zone + - ipv4-address-no-zone + - ipv6-address-no-zone"; + reference + "RFC 6991: Common YANG Data Types"; + } + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + /*** collection of types related to protocol fields ***/ + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code Point + that may be used for marking packets in a traffic stream. + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The ipv6-flow-label type represents the flow identifier or Flow + Label in an IPv6 packet header that may be used to + discriminate traffic flows. + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport-layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + /*** collection of types related to autonomous systems ***/ + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASes. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4001: Textual Conventions for Internet Network Addresses + RFC 6793: BGP Support for Four-Octet Autonomous System (AS) + Number Space"; + } + /*** collection of types related to IP addresses and hostnames ***/ + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representation + implies the IP version. This type supports scoped addresses + by allowing zone identifiers in the address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + The canonical format for the zone index is the numerical + format"; + } + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + The canonical format of IPv6 addresses uses the textual + representation defined in Section 4 of RFC 5952. The + canonical format for the zone index is the numerical + format as described in Section 11.2 of RFC 4007."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + typedef ip-address-no-zone { + type union { + type inet:ipv4-address-no-zone; + type inet:ipv6-address-no-zone; + } + description + "The ip-address-no-zone type represents an IP address and is + IP version neutral. The format of the textual representation + implies the IP version. This type does not support scoped + addresses since it does not allow zone identifiers in the + address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + typedef ipv4-address-no-zone { + type inet:ipv4-address { + pattern '[0-9\.]*'; + } + description + "An IPv4 address without a zone index. This type, derived from + ipv4-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + } + typedef ipv6-address-no-zone { + type inet:ipv6-address { + pattern '[0-9a-fA-F:\.]*'; + } + description + "An IPv6 address without a zone index. This type, derived from + ipv6-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 128. + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, the IPv6 address is represented + as defined in Section 4 of RFC 5952."; + reference + "RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + /*** collection of domain name and URI types ***/ + typedef domain-name { + type string { + pattern + '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + length "1..253"; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitly or may depend on the configuration of the + resolver. + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be A-labels as per RFC 5890."; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 5890: Internationalized Domain Names in Applications + (IDNA): Definitions and Document Framework"; + } + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } +} diff --git a/demo/protobuf_getting_started/yang/deps/ietf-yang-types.yang b/demo/protobuf_getting_started/yang/deps/ietf-yang-types.yang new file mode 100644 index 000000000..2a914e6f7 --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/ietf-yang-types.yang @@ -0,0 +1,404 @@ +module ietf-yang-types { + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types"; + prefix "yang"; + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + contact + "WG Web: + WG List: + WG Chair: David Kessens + + WG Chair: Juergen Schoenwaelder + + Editor: Juergen Schoenwaelder + "; + description + "This module contains a collection of generally useful derived + YANG data types. + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + revision 2013-07-15 { + description + "This revision adds the following new data types: + - yang-identifier + - hex-string + - uuid + - dotted-quad"; + reference + "RFC 6991: Common YANG Data Types"; + } + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + /*** collection of counter and gauge types ***/ + typedef counter32 { + type uint32; + description + "The counter32 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter32 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + The counter32 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter32. + In the value set and its semantics, this type is equivalent + to the Counter32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + typedef zero-based-counter32 { + type yang:counter32; + default "0"; + description + "The zero-based-counter32 type represents a counter32 + that has the defined 'initial' value zero. + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter32 textual convention of the SMIv2."; + reference + "RFC 4502: Remote Network Monitoring Management Information + Base Version 2"; + } + typedef counter64 { + type uint64; + description + "The counter64 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter64 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + The counter64 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter64. + In the value set and its semantics, this type is equivalent + to the Counter64 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + typedef zero-based-counter64 { + type yang:counter64; + default "0"; + description + "The zero-based-counter64 type represents a counter64 that + has the defined 'initial' value zero. + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter64 textual convention of the SMIv2."; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + typedef gauge32 { + type uint32; + description + "The gauge32 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^32-1 (4294967295 decimal), and + the minimum value cannot be smaller than 0. The value of + a gauge32 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge32 also decreases (increases). + In the value set and its semantics, this type is equivalent + to the Gauge32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + typedef gauge64 { + type uint64; + description + "The gauge64 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^64-1 (18446744073709551615), and + the minimum value cannot be smaller than 0. The value of + a gauge64 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge64 also decreases (increases). + In the value set and its semantics, this type is equivalent + to the CounterBasedGauge64 SMIv2 textual convention defined + in RFC 2856"; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + /*** collection of identifier-related types ***/ + typedef object-identifier { + type string { + pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))' + + '(\.(0|([1-9]\d*)))*'; + } + description + "The object-identifier type represents administratively + assigned names in a registration-hierarchical-name tree. + Values of this type are denoted as a sequence of numerical + non-negative sub-identifier values. Each sub-identifier + value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers + are separated by single dots and without any intermediate + whitespace. + The ASN.1 standard restricts the value space of the first + sub-identifier to 0, 1, or 2. Furthermore, the value space + of the second sub-identifier is restricted to the range + 0 to 39 if the first sub-identifier is 0 or 1. Finally, + the ASN.1 standard requires that an object identifier + has always at least two sub-identifiers. The pattern + captures these restrictions. + Although the number of sub-identifiers is not limited, + module designers should realize that there may be + implementations that stick with the SMIv2 limit of 128 + sub-identifiers. + This type is a superset of the SMIv2 OBJECT IDENTIFIER type + since it is not restricted to 128 sub-identifiers. Hence, + this type SHOULD NOT be used to represent the SMIv2 OBJECT + IDENTIFIER type; the object-identifier-128 type SHOULD be + used instead."; + reference + "ISO9834-1: Information technology -- Open Systems + Interconnection -- Procedures for the operation of OSI + Registration Authorities: General procedures and top + arcs of the ASN.1 Object Identifier tree"; + } + typedef object-identifier-128 { + type object-identifier { + pattern '\d*(\.\d*){1,127}'; + } + description + "This type represents object-identifiers restricted to 128 + sub-identifiers. + In the value set and its semantics, this type is equivalent + to the OBJECT IDENTIFIER type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + typedef yang-identifier { + type string { + length "1..max"; + pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*'; + pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*'; + } + description + "A YANG identifier string as defined by the 'identifier' + rule in Section 12 of RFC 6020. An identifier must + start with an alphabetic character or an underscore + followed by an arbitrary sequence of alphabetic or + numeric characters, underscores, hyphens, or dots. + A YANG identifier MUST NOT start with any possible + combination of the lowercase or uppercase character + sequence 'xml'."; + reference + "RFC 6020: YANG - A Data Modeling Language for the Network + Configuration Protocol (NETCONF)"; + } + /*** collection of types related to date and time***/ + typedef date-and-time { + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + + '(Z|[\+\-]\d{2}:\d{2})'; + } + description + "The date-and-time type is a profile of the ISO 8601 + standard for representation of dates and times using the + Gregorian calendar. The profile is defined by the + date-time production in Section 5.6 of RFC 3339. + The date-and-time type is compatible with the dateTime XML + schema type with the following notable exceptions: + (a) The date-and-time type does not allow negative years. + (b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z + all represent the same time zone in dateTime. + (c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using + the time-offset 'Z'. + This type is not equivalent to the DateAndTime textual + convention of the SMIv2 since RFC 3339 uses a different + separator between full-date and full-time and provides + higher resolution of time-secfrac. + The canonical format for date-and-time values with a known time + zone uses a numeric time zone offset that is calculated using + the device's configured known offset to UTC time. A change of + the device's offset to UTC time will cause date-and-time values + to change accordingly. Such changes might happen periodically + in case a server follows automatically daylight saving time + (DST) time zone offset changes. The canonical format for + date-and-time values with an unknown time zone (usually + referring to the notion of local time) uses the time-offset + -00:00."; + reference + "RFC 3339: Date and Time on the Internet: Timestamps + RFC 2579: Textual Conventions for SMIv2 + XSD-TYPES: XML Schema Part 2: Datatypes Second Edition"; + } + typedef timeticks { + type uint32; + description + "The timeticks type represents a non-negative integer that + represents the time, modulo 2^32 (4294967296 decimal), in + hundredths of a second between two epochs. When a schema + node is defined that uses this type, the description of + the schema node identifies both of the reference epochs. + In the value set and its semantics, this type is equivalent + to the TimeTicks type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + typedef timestamp { + type yang:timeticks; + description + "The timestamp type represents the value of an associated + timeticks schema node at which a specific occurrence + happened. The specific occurrence must be defined in the + description of any schema node defined using this type. When + the specific occurrence occurred prior to the last time the + associated timeticks attribute was zero, then the timestamp + value is zero. Note that this requires all timestamp values + to be reset to zero when the value of the associated timeticks + attribute reaches 497+ days and wraps around to zero. + The associated timeticks schema node must be specified + in the description of any schema node using this type. + In the value set and its semantics, this type is equivalent + to the TimeStamp textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + /*** collection of generic address types ***/ + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "Represents media- or physical-level addresses represented + as a sequence octets, each octet represented by two hexadecimal + numbers. Octets are separated by colons. The canonical + representation uses lowercase characters. + In the value set and its semantics, this type is equivalent + to the PhysAddress textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + } + description + "The mac-address type represents an IEEE 802 MAC address. + The canonical representation uses lowercase characters. + In the value set and its semantics, this type is equivalent + to the MacAddress textual convention of the SMIv2."; + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture + RFC 2579: Textual Conventions for SMIv2"; + } + /*** collection of XML-specific types ***/ + typedef xpath1.0 { + type string; + description + "This type represents an XPATH 1.0 expression. + When a schema node is defined that uses this type, the + description of the schema node MUST specify the XPath + context in which the XPath expression is evaluated."; + reference + "XPATH: XML Path Language (XPath) Version 1.0"; + } + /*** collection of string types ***/ + typedef hex-string { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "A hexadecimal string with octets represented as hex digits + separated by colons. The canonical representation uses + lowercase characters."; + } + typedef uuid { + type string { + pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-' + + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'; + } + description + "A Universally Unique IDentifier in the string representation + defined in RFC 4122. The canonical representation uses + lowercase characters. + The following is an example of a UUID in string representation: + f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + "; + reference + "RFC 4122: A Universally Unique IDentifier (UUID) URN + Namespace"; + } + typedef dotted-quad { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; + } + description + "An unsigned 32-bit number expressed in the dotted-quad + notation, i.e., four octets written as decimal numbers + and separated with the '.' (full stop) character."; + } +} diff --git a/demo/protobuf_getting_started/yang/deps/openconfig-bgp-errors.yang b/demo/protobuf_getting_started/yang/deps/openconfig-bgp-errors.yang new file mode 100644 index 000000000..07a464de8 --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/openconfig-bgp-errors.yang @@ -0,0 +1,405 @@ +submodule openconfig-bgp-errors { + + belongs-to openconfig-bgp-types { + prefix "oc-bgp-types"; + } + + import openconfig-extensions { prefix "oc-ext"; } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + netopenconfig@googlegroups.com"; + + description + "This module defines BGP NOTIFICATION message error codes + and subcodes"; + + oc-ext:openconfig-version "4.0.1"; + + revision "2017-07-30" { + description + "Clarification of add-paths send-max leaf"; + reference "4.0.1"; + } + + revision "2017-07-10" { + description + "Add error notifications; moved add-paths config; add AS + prepend policy features; removed unneeded config leaves"; + reference "4.0.0"; + } + + + + identity BGP_ERROR_CODE { + description + "Indicates the error type in a BGP NOTIFICATION message"; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + identity BGP_ERROR_SUBCODE { + description + "Provides more specific information about the nature of the + error reported in a NOTIFICATION message. Each Error + Code may have one or more Error Subcodes associated with it."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + + identity UNSPECIFIC { + base BGP_ERROR_SUBCODE; + description + "The error subcode field is unspecific when the NOTIFICATION + message does not include any specific error subcode (i.e.., + value 0)."; + } + + identity MESSAGE_HEADER_ERROR { + base BGP_ERROR_CODE; + description + "Errors detected while processing the Message Header"; + } + + identity OPEN_MESSAGE_ERROR { + base BGP_ERROR_CODE; + description + "Errors detected while processing the OPEN message"; + } + + identity UPDATE_MESSAGE_ERROR { + base BGP_ERROR_CODE; + description + "Errors detected while processing the UPDATE message"; + } + + identity HOLD_TIMER_EXPIRED { + base BGP_ERROR_CODE; + description + "Indicates that the system did not receive successive + KEEPALIVE, UPDATE, and/or NOTIFICATION messages within the + period specified in the Hold Time field of the OPEN message"; + } + + identity FINITE_STATE_MACHINE_ERROR { + base BGP_ERROR_CODE; + description + "Error detected by the BGP Finite State Machine + (e.g., receipt of an unexpected event)"; + } + + identity CEASE { + base BGP_ERROR_CODE; + description + "Sent by a BGP peer to close its BGP connection in absence of + any fatal errors. If the BGP speaker terminates its + connection with a neihbor because the number of prefixes + received exceeds the configured upper bound, the speaker must + send the neighbor a NOTIFICATION message with the Cease + error code."; + } + + identity ROUTE_REFRESH_MESSAGE_ERROR { + base BGP_ERROR_CODE; + description + "The length, excluding the fixed-size message header, of the + received ROUTE-REFRESH message with Message Subtype 1 and 2 is + not 4. Applicable only when a BGP speaker has received the + 'Enhanced Route Refresh Capability' from a peer"; + reference + "RFC 7313 - Enhanced Route Refresh Capability for BGP-4"; + } + + identity MESSAGE_HEADER_SUBCODE { + base BGP_ERROR_SUBCODE; + description + "Error subcode definitions for Message Header error + notifications"; + } + + identity CONNECTION_NOT_SYNCHRONIZED { + base MESSAGE_HEADER_SUBCODE; + description + "Marker field of the message header is not all ones as + expected"; + } + + identity BAD_MESSAGE_LENGTH { + base MESSAGE_HEADER_SUBCODE; + description + "Indicates the message has an erroneous length with one + or more of the following: + + - the Length field of the message header is less than 19 or + greater than 4096 + + - the Length field of an OPEN message is less than the minimum + length of the OPEN message + + - the Length field of an UPDATE message is less than the + minimum length of the UPDATE message + + - the Length field of a KEEPALIVE message is not equal to 19 + + - the Length field of a NOTIFICATION message is less than the + minimum length of the NOTIFICATION message + + The erroneous Length field must be reported in the + NOTIFICATION data."; + } + + identity BAD_MESSAGE_TYPE { + base MESSAGE_HEADER_SUBCODE; + description + "Type field of the message header is not recognized. The + erroneous type field must be reported in the NOTIFICATION + data"; + } + + identity OPEN_MESSAGE_SUBCODE { + base BGP_ERROR_SUBCODE; + description + "Error subcode definitions for OPEN message error + notifications"; + } + + identity UNSUPPORTED_VERSION_NUMBER { + base OPEN_MESSAGE_SUBCODE; + description + "Version number in the Version field of the received OPEN + message is not supported"; + } + + identity BAD_PEER_AS { + base OPEN_MESSAGE_SUBCODE; + description + "Autonomous System field of the OPEN message is unacceptable"; + } + + identity BAD_BGP_IDENTIFIER { + base OPEN_MESSAGE_SUBCODE; + description + "BGP Identifier field of the OPEN message is syntactically + incorrect"; + } + + identity UNSUPPORTED_OPTIONAL_PARAMETER { + base OPEN_MESSAGE_SUBCODE; + description + "One of the Optional Parameters in the OPEN message is not + recognized"; + } + + identity UNACCEPTABLE_HOLD_TIME { + base OPEN_MESSAGE_SUBCODE; + description + "Hold Time field of the OPEN message is unacceptable"; + } + + identity UNSUPPORTED_CAPABILITY { + base OPEN_MESSAGE_SUBCODE; + description + "Inidicates that the peer does not support capabilities + advertisement -- the peer may send this subcode in response to + an OPEN message that carries the Capabilities Optional + Parameter"; + reference + "RFC 5492 - Capabilities Advertisement with BGP-4"; + } + + identity UPDATE_MESSAGE_SUBCODE { + base BGP_ERROR_SUBCODE; + description + "Error subcode definitions for UPDATE message error + notifications"; + } + + identity MALFORMED_ATTRIBUTE_LIST { + base UPDATE_MESSAGE_SUBCODE; + description + "Inidicates Withdrawn Routes Length or Total Attribute Length + is too large, or + + An attribute appears more than once in the UPDATE message"; + } + + identity UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE { + base UPDATE_MESSAGE_SUBCODE; + description + "One or more of the well-known mandatory attributes are not + recognized"; + } + + identity MISSING_WELL_KNOWN_ATTRIBUTE { + base UPDATE_MESSAGE_SUBCODE; + description + "One or more of the well-known mandatory attributes are not + present"; + } + + identity ATTRIBUTE_FLAGS_ERROR { + base UPDATE_MESSAGE_SUBCODE; + description + "Attribute has Attribute Flags that conflict with the + Attribute Type Code"; + } + + identity ATTRIBUTE_LENGTH_ERROR { + base UPDATE_MESSAGE_SUBCODE; + description + "Attribute has an Attribute Length that conflicts with the + expected length (based on the attribute type code)"; + } + + identity INVALID_ORIGIN_ATTRIBUTE { + base UPDATE_MESSAGE_SUBCODE; + description + "ORIGIN attribute has an undefined value"; + } + + identity INVALID_NEXT_HOP_ATTRIBUTE { + base UPDATE_MESSAGE_SUBCODE; + description + "The NEXT_HOP attribute field is syntactically incorrect"; + } + + identity OPTIONAL_ATTRIBUTE_ERROR { + base UPDATE_MESSAGE_SUBCODE; + description + "An error is detected in the value of a recognized optional + attribute (such an attribute must be discarded)"; + } + + identity INVALID_NETWORK_FIELD { + base UPDATE_MESSAGE_SUBCODE; + description + "The NLRI field in the UPDATE message is syntactically + incorrect"; + } + + identity MALFORMED_AS_PATH { + base UPDATE_MESSAGE_SUBCODE; + description + "The AS_PATH attribute is syntactically incorrect"; + } + + identity FINITE_STATE_MACHINE_SUBCODE { + base BGP_ERROR_SUBCODE; + description + "Error subcode definitions for BGP finite state machine + errors."; + reference + "RFC 6608 - Subcodes for BGP Finite State Machine Error"; + } + + identity RECEIVE_UNEXPECTED_MESSAGE_OPENSENT { + base FINITE_STATE_MACHINE_SUBCODE; + description + "The peer BGP speaker received an unexpected message from + the local system while the peer speaker session was in the + OpenSent state"; + } + + identity RECEIVE_UNEXPECTED_MESSAGE_OPENCONFIRM { + base FINITE_STATE_MACHINE_SUBCODE; + description + "The peer BGP speaker received an unexpected message from + the local system while the peer speaker session was in the + OpenConfirm state"; + } + + identity RECEIVE_UNEXPECTED_MESSAGE_ESTABLISHED { + base FINITE_STATE_MACHINE_SUBCODE; + description + "The peer BGP speaker received an unexpected message from + the local system while the peer speaker session was in the + Established state"; + } + + identity CEASE_SUBCODE { + base BGP_ERROR_SUBCODE; + description + "Error subcode definitions for Cease notification messages"; + reference + "RFC 4486 - Subcodes for BGP Cease Notification Message"; + } + + identity MAX_NUM_PREFIXES_REACHED { + base CEASE_SUBCODE; + description + "The peer BGP speaker terminated its peering with the local + system because the number of address prefixes received + exceeds a locally configured upper bound"; + } + + identity ADMINISTRATIVE_SHUTDOWN { + base CEASE_SUBCODE; + description + "The peer BGP speaker administratively shut down its peering + with the local system"; + } + + identity PEER_DE_CONFIGURED { + base CEASE_SUBCODE; + description + "The peer BGP speaker de-configure the peering with the local + system"; + } + + identity ADMINISTRATIVE_RESET { + base CEASE_SUBCODE; + description + "The peer BGP speaker administratively reset the peering with + the local system"; + } + + identity CONNECTION_REJECTED { + base CEASE_SUBCODE; + description + "The peer BGP speaker disallowed the BGP connection to the + local system after the peer speaker accepted a transport + protocol connection"; + } + + identity OTHER_CONFIG_CHANGE { + base CEASE_SUBCODE; + description + "The peer BGP speaker administratively reset the peering with + the local sytem due to a configuration change that is not + covered by another subcode."; + } + + identity CONN_COLLISION_RESOLUTION { + base CEASE_SUBCODE; + description + "The peer BGP speaker sent a CEASE NOTIFICATION as a result of + the collision resolution procedure described in RFC 4271"; + } + + identity OUT_OF_RESOURCES { + base CEASE_SUBCODE; + description + "The peer BGP speaker ran out of resources (e.g., memory) and + reset the session with the local system"; + } + + identity ROUTE_REFRESH_SUBCODE { + base BGP_ERROR_SUBCODE; + description + "Error subcode definitions for the ROUTE-REFRESH message + error"; + } + + identity INVALID_MESSAGE_LENGTH { + base ROUTE_REFRESH_SUBCODE; + description + "The length, excluding the fixed-size message header, of the + received ROUTE-REFRESH message with Message Subtype 1 and 2 + is not 4"; + } +} diff --git a/demo/protobuf_getting_started/yang/deps/openconfig-bgp-types.yang b/demo/protobuf_getting_started/yang/deps/openconfig-bgp-types.yang new file mode 100644 index 000000000..1e58de2b1 --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/openconfig-bgp-types.yang @@ -0,0 +1,554 @@ +module openconfig-bgp-types { + yang-version "1"; + + namespace "http://openconfig.net/yang/bgp-types"; + + prefix "oc-bgp-types"; + + import openconfig-types { prefix "oc-types"; } + import openconfig-inet-types { prefix "oc-inet"; } + import openconfig-extensions { prefix "oc-ext"; } + + // Include definitions of BGP error notifications + include openconfig-bgp-errors; + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + netopenconfig@googlegroups.com"; + + description + "This module contains general data definitions for use in BGP + policy. It can be imported by modules that make use of BGP + attributes"; + + oc-ext:openconfig-version "4.0.1"; + + revision "2017-07-30" { + description + "Clarification of add-paths send-max leaf"; + reference "4.0.1"; + } + + revision "2017-07-10" { + description + "Add error notifications; moved add-paths config; add AS + prepend policy features; removed unneeded config leaves"; + reference "4.0.0"; + } + + revision "2017-02-02" { + description + "Bugfix to remove remaining global-level policy data"; + reference "3.0.1"; + } + + revision "2017-01-26" { + description + "Add dynamic neighbor support, migrate to OpenConfig types"; + reference "3.0.0"; + } + + revision "2016-06-21" { + description + "OpenConfig BGP refactor"; + reference "2.1.1"; + } + + + identity BGP_CAPABILITY { + description "Base identity for a BGP capability"; + } + + identity MPBGP { + base BGP_CAPABILITY; + description + "Multi-protocol extensions to BGP"; + reference "RFC2858"; + } + + identity ROUTE_REFRESH { + base BGP_CAPABILITY; + description + "The BGP route-refresh functionality"; + reference "RFC2918"; + } + + identity ASN32 { + base BGP_CAPABILITY; + description + "4-byte (32-bit) AS number functionality"; + reference "RFC6793"; + } + + identity GRACEFUL_RESTART { + base BGP_CAPABILITY; + description + "Graceful restart functionality"; + reference "RFC4724"; + } + + identity ADD_PATHS { + base BGP_CAPABILITY; + description + "BGP add-paths"; + reference "draft-ietf-idr-add-paths"; + } + + identity AFI_SAFI_TYPE { + description + "Base identity type for AFI,SAFI tuples for BGP-4"; + reference "RFC4760 - multiprotocol extensions for BGP-4"; + } + + identity IPV4_UNICAST { + base AFI_SAFI_TYPE; + description + "IPv4 unicast (AFI,SAFI = 1,1)"; + reference "RFC4760"; + } + + identity IPV6_UNICAST { + base AFI_SAFI_TYPE; + description + "IPv6 unicast (AFI,SAFI = 2,1)"; + reference "RFC4760"; + } + + identity IPV4_LABELED_UNICAST { + base AFI_SAFI_TYPE; + description + "Labeled IPv4 unicast (AFI,SAFI = 1,4)"; + reference "RFC3107"; + } + + identity IPV6_LABELED_UNICAST { + base AFI_SAFI_TYPE; + description + "Labeled IPv6 unicast (AFI,SAFI = 2,4)"; + reference "RFC3107"; + } + + identity L3VPN_IPV4_UNICAST { + base AFI_SAFI_TYPE; + description + "Unicast IPv4 MPLS L3VPN (AFI,SAFI = 1,128)"; + reference "RFC4364"; + } + + identity L3VPN_IPV6_UNICAST { + base AFI_SAFI_TYPE; + description + "Unicast IPv6 MPLS L3VPN (AFI,SAFI = 2,128)"; + reference "RFC4659"; + } + + identity L3VPN_IPV4_MULTICAST { + base AFI_SAFI_TYPE; + description + "Multicast IPv4 MPLS L3VPN (AFI,SAFI = 1,129)"; + reference "RFC6514"; + } + + identity L3VPN_IPV6_MULTICAST { + base AFI_SAFI_TYPE; + description + "Multicast IPv6 MPLS L3VPN (AFI,SAFI = 2,129)"; + reference "RFC6514"; + } + + identity L2VPN_VPLS { + base AFI_SAFI_TYPE; + description + "BGP-signalled VPLS (AFI,SAFI = 25,65)"; + reference "RFC4761"; + } + + identity L2VPN_EVPN { + base AFI_SAFI_TYPE; + description + "BGP MPLS Based Ethernet VPN (AFI,SAFI = 25,70)"; + } + + identity BGP_WELL_KNOWN_STD_COMMUNITY { + description + "Reserved communities within the standard community space + defined by RFC1997. These communities must fall within the + range 0x00000000 to 0xFFFFFFFF"; + reference "RFC1997"; + } + + identity NO_EXPORT { + base BGP_WELL_KNOWN_STD_COMMUNITY; + description + "Do not export NLRI received carrying this community outside + the bounds of this autonomous system, or this confederation if + the local autonomous system is a confederation member AS. This + community has a value of 0xFFFFFF01."; + reference "RFC1997"; + } + + identity NO_ADVERTISE { + base BGP_WELL_KNOWN_STD_COMMUNITY; + description + "All NLRI received carrying this community must not be + advertised to other BGP peers. This community has a value of + 0xFFFFFF02."; + reference "RFC1997"; + } + + identity NO_EXPORT_SUBCONFED { + base BGP_WELL_KNOWN_STD_COMMUNITY; + description + "All NLRI received carrying this community must not be + advertised to external BGP peers - including over confederation + sub-AS boundaries. This community has a value of 0xFFFFFF03."; + reference "RFC1997"; + } + + identity NOPEER { + base BGP_WELL_KNOWN_STD_COMMUNITY; + description + "An autonomous system receiving NLRI tagged with this community + is advised not to readvertise the NLRI to external bi-lateral + peer autonomous systems. An AS may also filter received NLRI + from bilateral peer sessions when they are tagged with this + community value"; + reference "RFC3765"; + } + + typedef bgp-session-direction { + type enumeration { + enum INBOUND { + description + "Refers to all NLRI received from the BGP peer"; + } + enum OUTBOUND { + description + "Refers to all NLRI advertised to the BGP peer"; + } + } + description + "Type to describe the direction of NLRI transmission"; + } + + typedef bgp-well-known-community-type { + type identityref { + base BGP_WELL_KNOWN_STD_COMMUNITY; + } + description + "Type definition for well-known IETF community attribute + values"; + reference + "IANA Border Gateway Protocol (BGP) Well Known Communities"; + } + + + typedef bgp-std-community-type { + // TODO: further refine restrictions and allowed patterns + // 4-octet value: + // 2 octets + // 2 octets + type union { + type uint32 { + // per RFC 1997, 0x00000000 - 0x0000FFFF and 0xFFFF0000 - + // 0xFFFFFFFF are reserved + } + type string { + pattern '^(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + } + description + "Type definition for standard commmunity attributes represented as + a integer value, or a string of the form N:M where N and M are + integers between 0 and 65535."; + reference "RFC 1997 - BGP Communities Attribute"; + } + + typedef bgp-ext-community-type { + type union { + type string { + // Type 1: 2-octet global and 4-octet local + // (AS number) (Integer) + pattern '^(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):' + + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}' + + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|' + + '[1-9][0-9]{1,8}|[0-9])$'; + } + type string { + // Type 2: 4-octet global and 2-octet local + // (ipv4-address) (integer) + pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|' + + '2[0-4][0-9]|25[0-5]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + type string { + // RFC5668: 4-octet global and 2-octet local + // (AS number) (integer) + pattern '^(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}' + + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|' + + '[1-9][0-9]{1,8}|[0-9]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + type string { + // route-target with Type 1 + // route-target:(ASN):(local-part) + pattern '^route\-target:' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):' + + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}' + + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|' + + '[1-9][0-9]{1,8}|[0-9])$'; + } + type string { + // route-target with Type 2 + // route-target:(IPv4):(local-part) + pattern '^route\-target:' + + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|' + + '2[0-4][0-9]|25[0-5]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + type string { + // 4-byte AS Type 1 route-target + pattern '^route\-target:' + + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}' + + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|' + + '[1-9][0-9]{1,8}|[0-9]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + type string { + // route-origin with Type 1 + pattern '^route\-origin:' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):' + + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}' + + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|' + + '[1-9][0-9]{1,8}|[0-9])$'; + } + type string { + // route-origin with Type 2 + pattern '^route\-origin:' + + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|' + + '2[0-4][0-9]|25[0-5]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + type string { + // 4-byte AS Type 1 route-origin + pattern '^route\-origin:' + + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}' + + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|' + + '[1-9][0-9]{1,8}|[0-9]):' + + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' + + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$'; + } + } + description + "Type definition for extended community attributes. In the case that + common communities are utilised, they are represented as a string + of the form: + - <2b AS>:<4b value> per RFC4360 section 3.1 + - <4b IPv4>:<2b value> per RFC4360 section 3.2 + - <4b AS>:<2b value> per RFC5668 section 2. + - route-target:<2b AS>:<4b value> per RFC4360 section 4 + - route-target:<4b IPv4>:<2b value> per RFC4360 section 4 + - route-origin:<2b ASN>:<4b value> per RFC4360 section 5 + - route-origin:<4b IPv4>:<2b value> per RFC4360 section 5"; + reference + "RFC 4360 - BGP Extended Communities Attribute + RFC 5668 - 4-Octet AS Specific BGP Extended Community"; + } + + typedef bgp-ext-community-recv-type { + type union { + type bgp-ext-community-type; + type binary { + length 8; + } + } + description + "A type definition utilised to define the extended community + in a context where the system is receiving the extended + community from an external source, such that the value may be + unknown. In the case that the received extended community is + unknown it is defined to be a 8-octet quantity formatted + according to RFC4360: + + Type Field: 1 or 2 octets. + Value Field: Remaining octets. + + The high-order octet of the type field is encoded such that + bit 0 indicates whether the extended community type is IANA + assigned; and bit 1 indicates whether the extended community + is transitive. The remaining bits of the high-order type + field must be interpreted to determine whether the low-order + type field should be parsed, or whether the entire remainder + of the extended community is a value."; + reference + "RFC 4360 - BGP Extended Communities Attribute + RFC 5668 - 4-Octet AS Specific BGP Extended Community"; + } + + typedef bgp-community-regexp-type { + // TODO: needs more work to decide what format these regexps can + // take. + type oc-types:std-regexp; + description + "Type definition for communities specified as regular + expression patterns"; + } + + typedef bgp-origin-attr-type { + type enumeration { + enum IGP { + description + "Origin of the NLRI is internal"; + } + enum EGP { + description + "Origin of the NLRI is EGP"; + } + enum INCOMPLETE { + description + "Origin of the NLRI is neither IGP or EGP"; + } + } + description + "Type definition for standard BGP origin attribute"; + reference "RFC 4271 - A Border Gateway Protocol 4 (BGP-4), + Sec 4.3"; + } + + typedef peer-type { + type enumeration { + enum INTERNAL { + description + "Internal (iBGP) peer"; + } + enum EXTERNAL { + description + "External (eBGP) peer"; + } + } + description + "Labels a peer or peer group as explicitly internal or + external"; + } + + identity REMOVE_PRIVATE_AS_OPTION { + description + "Base identity for options for removing private autonomous + system numbers from the AS_PATH attribute"; + } + + identity PRIVATE_AS_REMOVE_ALL { + base REMOVE_PRIVATE_AS_OPTION; + description + "Strip all private autonmous system numbers from the AS_PATH. + This action is performed regardless of the other content of the + AS_PATH attribute, and for all instances of private AS numbers + within that attribute."; + } + + identity PRIVATE_AS_REPLACE_ALL { + base REMOVE_PRIVATE_AS_OPTION; + description + "Replace all instances of private autonomous system numbers in + the AS_PATH with the local BGP speaker's autonomous system + number. This action is performed regardless of the other + content of the AS_PATH attribute, and for all instances of + private AS number within that attribute."; + } + + typedef remove-private-as-option { + type identityref { + base REMOVE_PRIVATE_AS_OPTION; + } + description + "Set of options for configuring how private AS path numbers + are removed from advertisements"; + } + + typedef rr-cluster-id-type { + type union { + type uint32; + type oc-inet:ipv4-address; + } + description + "Union type for route reflector cluster ids: + option 1: 4-byte number + option 2: IP address"; + } + + typedef community-type { + type enumeration { + enum STANDARD { + description "Send only standard communities"; + } + enum EXTENDED { + description "Send only extended communities"; + } + enum BOTH { + description "Send both standard and extended communities"; + } + enum NONE { + description "Do not send any community attribute"; + } + } + description + "type describing variations of community attributes: + STANDARD: standard BGP community [rfc1997] + EXTENDED: extended BGP community [rfc4360] + BOTH: both standard and extended community"; + } + + + typedef as-path-segment-type { + type enumeration { + enum AS_SEQ { + description + "Ordered set of autonomous systems that a route in + the UPDATE message has traversed"; + } + enum AS_SET { + description + "Unordered set of autonomous systems that a route in + the UPDATE message has traversed"; + } + enum AS_CONFED_SEQUENCE { + description + "Ordered set of Member Autonomous + Systems in the local confederation that the UPDATE message + has traversed"; + } + enum AS_CONFED_SET { + description + "Unordered set of Member Autonomous Systems + in the local confederation that the UPDATE message has + traversed"; + } + } + description + "Defines the types of BGP AS path segments."; + } +} diff --git a/demo/protobuf_getting_started/yang/deps/openconfig-extensions.yang b/demo/protobuf_getting_started/yang/deps/openconfig-extensions.yang new file mode 100644 index 000000000..f39ecf662 --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/openconfig-extensions.yang @@ -0,0 +1,91 @@ +module openconfig-extensions { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/openconfig-ext"; + + prefix "oc-ext"; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module provides extensions to the YANG language to allow + OpenConfig specific functionality and meta-data to be defined."; + + revision "2017-04-11" { + description + "rename password type to 'hashed' and clarify description"; + reference "0.3.0"; + } + + revision "2017-01-29" { + description + "Added extension for annotating encrypted values."; + reference "0.2.0"; + } + + revision "2015-10-09" { + description + "Initial OpenConfig public release"; + reference "0.1.0"; + } + + + // extension statements + extension openconfig-version { + argument "semver" { + yin-element false; + } + description + "The OpenConfig version number for the module. This is + expressed as a semantic version number of the form: + x.y.z + where: + * x corresponds to the major version, + * y corresponds to a minor version, + * z corresponds to a patch version. + This version corresponds to the model file within which it is + defined, and does not cover the whole set of OpenConfig models. + Where several modules are used to build up a single block of + functionality, the same module version is specified across each + file that makes up the module. + + A major version number of 0 indicates that this model is still + in development (whether within OpenConfig or with industry + partners), and is potentially subject to change. + + Following a release of major version 1, all modules will + increment major revision number where backwards incompatible + changes to the model are made. + + The minor version is changed when features are added to the + model that do not impact current clients use of the model. + + The patch-level version is incremented when non-feature changes + (such as bugfixes or clarifications to human-readable + descriptions that do not impact model functionality) are made + that maintain backwards compatibility. + + The version number is stored in the module meta-data."; + } + + extension openconfig-hashed-value { + description + "This extension provides an annotation on schema nodes to + indicate that the corresponding value should be stored and + reported in hashed form. + + Hash algorithms are by definition not reversible. Clients + reading the configuration or applied configuration for the node + should expect to receive only the hashed value. Values written + in cleartext will be hashed. This annotation may be used on + nodes such as secure passwords in which the device never reports + a cleartext value, even if the input is provided as cleartext."; + } +} diff --git a/demo/protobuf_getting_started/yang/deps/openconfig-inet-types.yang b/demo/protobuf_getting_started/yang/deps/openconfig-inet-types.yang new file mode 100644 index 000000000..2ed56638e --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/openconfig-inet-types.yang @@ -0,0 +1,332 @@ +module openconfig-inet-types { + + yang-version "1"; + namespace "http://openconfig.net/yang/types/inet"; + prefix "oc-inet"; + + import openconfig-extensions { prefix "oc-ext"; } + + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module contains a set of Internet address related + types for use in OpenConfig modules. + + Portions of this code were derived from IETF RFC 6021. + Please reproduce this note if possible. + + IETF code is subject to the following copyright and license: + Copyright (c) IETF Trust and the persons identified as authors of + the code. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in + Section 4.c of the IETF Trust's Legal Provisions Relating + to IETF Documents (http://trustee.ietf.org/license-info)."; + + oc-ext:openconfig-version "0.3.1"; + + revision 2017-08-24 { + description + "Minor formatting fixes."; + reference "0.3.1"; + } + + revision 2017-07-06 { + description + "Add domain-name and host typedefs"; + reference "0.3.0"; + } + + revision 2017-04-03 { + description + "Add ip-version typedef."; + reference "0.2.0"; + } + + revision 2017-04-03 { + description + "Update copyright notice."; + reference "0.1.1"; + } + + revision 2017-01-26 { + description + "Initial module for inet types"; + reference "0.1.0"; + } + + // IPv4 and IPv6 types. + + typedef ipv4-address { + type string { + pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' + + '[0-9]|25[0-5])$'; + } + description + "An IPv4 address in dotted quad notation using the default + zone."; + } + + typedef ipv4-address-zoned { + type string { + pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' + + '[0-9]|25[0-5])(%[a-zA-Z0-9_]+)$'; + } + description + "An IPv4 address in dotted quad notation. This type allows + specification of a zone index to disambiguate identical + address values. For link-local addresses, the index is + typically the interface index or interface name."; + } + + typedef ipv6-address { + type string { + pattern + // Must support compression through different lengths + // therefore this regexp is complex. + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')$'; + } + description + "An IPv6 address represented as either a full address; shortened + or mixed-shortened formats, using the default zone."; + } + + typedef ipv6-address-zoned { + type string { + pattern + // Must support compression through different lengths + // therefore this regexp is complex. + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')(%[a-zA-Z0-9_]+)$'; + } + description + "An IPv6 address represented as either a full address; shortened + or mixed-shortened formats. This type allows specification of + a zone index to disambiguate identical address values. For + link-local addresses, the index is typically the interface + index or interface name."; + } + + typedef ipv4-prefix { + type string { + pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' + + '[0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))$'; + } + description + "An IPv4 prefix represented in dotted quad notation followed by + a slash and a CIDR mask (0 <= mask <= 32)."; + } + + typedef ipv6-prefix { + type string { + pattern + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])$'; + } + description + "An IPv6 prefix represented in full, shortened, or mixed + shortened format followed by a slash and CIDR mask + (0 <= mask <= 128)."; + } + + typedef ip-address { + type union { + type ipv4-address; + type ipv6-address; + } + description + "An IPv4 or IPv6 address with no prefix specified."; + } + + typedef ip-prefix { + type union { + type ipv4-prefix; + type ipv6-prefix; + } + description + "An IPv4 or IPv6 prefix."; + } + + typedef ip-version { + type enumeration { + enum UNKNOWN { + value 0; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum IPV4 { + value 4; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum IPV6 { + value 6; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + Note that integer representation of the enumerated values + are not specified, and are not required to follow the + InetVersion textual convention in SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef domain-name { + type string { + length "1..253"; + pattern + '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + } + description + "The domain-name type represents a DNS domain name. + Fully quallified left to the models which utilize this type. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be encoded in punycode as described in RFC + 3492"; + } + + typedef host { + type union { + type ip-address; + type domain-name; + } + description + "The host type represents either an unzoned IP address or a DNS + domain name."; + } + + typedef as-number { + type uint32; + description + "A numeric identifier for an autonomous system (AS). An AS is a + single domain, under common administrative control, which forms + a unit of routing policy. Autonomous systems can be assigned a + 2-byte identifier, or a 4-byte identifier which may have public + or private scope. Private ASNs are assigned from dedicated + ranges. Public ASNs are assigned from ranges allocated by IANA + to the regional internet registries (RIRs)."; + reference + "RFC 1930 Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271 A Border Gateway Protocol 4 (BGP-4)"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "A differentiated services code point (DSCP) marking within the + IP header."; + reference + "RFC 2474 Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The IPv6 flow-label is a 20-bit value within the IPv6 header + which is optionally used by the source of the IPv6 packet to + label sets of packets for which special handling may be + required."; + reference + "RFC 2460 Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16; + description + "A 16-bit port number used by a transport protocol such as TCP + or UDP."; + reference + "RFC 768 User Datagram Protocol + RFC 793 Transmission Control Protocol"; + } + + typedef uri { + type string; + description + "An ASCII-encoded Uniform Resource Identifier (URI) as defined + in RFC 3986."; + reference + "RFC 3986 Uniform Resource Identifier (URI): Generic Syntax"; + } + + typedef url { + type string; + description + "An ASCII-encoded Uniform Resource Locator (URL) as defined + in RFC 3986, section 1.1.3"; + reference + "RFC 3986, paragraph 1.1.3"; + } + +} diff --git a/demo/protobuf_getting_started/yang/deps/openconfig-policy-types.yang b/demo/protobuf_getting_started/yang/deps/openconfig-policy-types.yang new file mode 100644 index 000000000..03270f33a --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/openconfig-policy-types.yang @@ -0,0 +1,187 @@ +module openconfig-policy-types { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/policy-types"; + + prefix "oc-pol-types"; + + // import some basic types + import ietf-yang-types { prefix yang; } + import openconfig-extensions { prefix oc-ext; } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + netopenconfig@googlegroups.com"; + + description + "This module contains general data definitions for use in routing + policy. It can be imported by modules that contain protocol- + specific policy conditions and actions."; + + oc-ext:openconfig-version "3.0.0"; + + revision "2017-07-14" { + description + "Replace policy choice node/type with policy-result + enumeration;simplified defined set naming;removed generic + IGP actions; migrate to OpenConfig types; added mode for + prefix sets"; + reference "3.0.0"; + } + + revision "2016-05-12" { + description + "OpenConfig public release"; + reference "2.0.1"; + } + + // identity statements + + identity ATTRIBUTE_COMPARISON { + description + "base type for supported comparison operators on route + attributes"; + } + + identity ATTRIBUTE_EQ { + base ATTRIBUTE_COMPARISON; + description "== comparison"; + } + + identity ATTRIBUTE_GE { + base ATTRIBUTE_COMPARISON; + description ">= comparison"; + } + + identity ATTRIBUTE_LE { + base ATTRIBUTE_COMPARISON; + description "<= comparison"; + } + + typedef match-set-options-type { + type enumeration { + enum ANY { + description "match is true if given value matches any member + of the defined set"; + } + enum ALL { + description "match is true if given value matches all + members of the defined set"; + } + enum INVERT { + description "match is true if given value does not match any + member of the defined set"; + } + } + default ANY; + description + "Options that govern the behavior of a match statement. The + default behavior is ANY, i.e., the given value matches any + of the members of the defined set"; + } + + typedef match-set-options-restricted-type { + type enumeration { + enum ANY { + description "match is true if given value matches any member + of the defined set"; + } + enum INVERT { + description "match is true if given value does not match any + member of the defined set"; + } + } + default ANY; + description + "Options that govern the behavior of a match statement. The + default behavior is ANY, i.e., the given value matches any + of the members of the defined set. Note this type is a + restricted version of the match-set-options-type."; + //TODO: restriction on enumerated types is only allowed in + //YANG 1.1. Until then, we will require this additional type + } + + grouping attribute-compare-operators { + description "common definitions for comparison operations in + condition statements"; + + leaf operator { + type identityref { + base ATTRIBUTE_COMPARISON; + } + description + "type of comparison to be performed"; + } + + leaf value { + type uint32; + description + "value to compare with the community count"; + } + } + + typedef tag-type { + type union { + type uint32; + type yang:hex-string; + } + description "type for expressing route tags on a local system, + including IS-IS and OSPF; may be expressed as either decimal or + hexidecimal integer"; + reference + "RFC 2178 OSPF Version 2 + RFC 5130 A Policy Control Mechanism in IS-IS Using + Administrative Tags"; + } + + identity INSTALL_PROTOCOL_TYPE { + description + "Base type for protocols which can install prefixes into the + RIB"; + } + + identity BGP { + base INSTALL_PROTOCOL_TYPE; + description "BGP"; + reference "RFC 4271"; + } + + identity ISIS { + base INSTALL_PROTOCOL_TYPE; + description "IS-IS"; + reference "ISO/IEC 10589"; + } + + identity OSPF { + base INSTALL_PROTOCOL_TYPE; + description "OSPFv2"; + reference "RFC 2328"; + } + + identity OSPF3 { + base INSTALL_PROTOCOL_TYPE; + description "OSPFv3"; + reference "RFC 5340"; + } + + identity STATIC { + base INSTALL_PROTOCOL_TYPE; + description "Locally-installed static route"; + } + + identity DIRECTLY_CONNECTED { + base INSTALL_PROTOCOL_TYPE; + description "A directly connected route"; + } + + identity LOCAL_AGGREGATE { + base INSTALL_PROTOCOL_TYPE; + description "Locally defined aggregate route"; + } +} diff --git a/demo/protobuf_getting_started/yang/deps/openconfig-types.yang b/demo/protobuf_getting_started/yang/deps/openconfig-types.yang new file mode 100644 index 000000000..fa76f8013 --- /dev/null +++ b/demo/protobuf_getting_started/yang/deps/openconfig-types.yang @@ -0,0 +1,332 @@ +module openconfig-types { + yang-version "1"; + + namespace "http://openconfig.net/yang/openconfig-types"; + + prefix "oc-types"; + + // import statements + import openconfig-extensions { prefix oc-ext; } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + netopenconfig@googlegroups.com"; + + description + "This module contains a set of general type definitions that + are used across OpenConfig models. It can be imported by modules + that make use of these types."; + + oc-ext:openconfig-version "0.3.3"; + + revision "2017-08-16" { + description + "Apply fix for ieetfloat32 length parameter"; + reference "0.3.3"; + } + + revision "2017-01-13" { + description + "Add ADDRESS_FAMILY identity"; + reference "0.3.2"; + } + + revision "2016-11-14" { + description + "Correct length of ieeefloat32"; + reference "0.3.1"; + } + + revision "2016-11-11" { + description + "Additional types - ieeefloat32 and routing-password"; + reference "0.3.0"; + } + + revision "2016-05-31" { + description + "OpenConfig public release"; + reference "0.2.0"; + } + + typedef percentage { + type uint8 { + range "0..100"; + } + description + "Integer indicating a percentage value"; + } + + typedef std-regexp { + type string; + description + "This type definition is a placeholder for a standard + definition of a regular expression that can be utilised in + OpenConfig models. Further discussion is required to + consider the type of regular expressions that are to be + supported. An initial proposal is POSIX compatible."; + } + + typedef timeticks64 { + type uint64; + description + "This type is based on the timeticks type defined in + RFC 6991, but with 64-bit width. It represents the time, + modulo 2^64, in hundredths of a second between two epochs."; + reference + "RFC 6991 - Common YANG Data Types"; + } + + typedef ieeefloat32 { + type binary { + length "4"; + } + description + "An IEEE 32-bit floating point number. The format of this number + is of the form: + 1-bit sign + 8-bit exponent + 23-bit fraction + The floating point value is calculated using: + (-1)**S * 2**(Exponent-127) * (1+Fraction)"; + } + + typedef routing-password { + type string; + description + "This type is indicative of a password that is used within + a routing protocol which can be returned in plain text to the + NMS by the local system. Such passwords are typically stored + as encrypted strings. Since the encryption used is generally + well known, it is possible to extract the original value from + the string - and hence this format is not considered secure. + Leaves specified with this type should not be modified by + the system, and should be returned to the end-user in plain + text. This type exists to differentiate passwords, which + may be sensitive, from other string leaves. It could, for + example, be used by the NMS to censor this data when + viewed by particular users."; + } + + grouping avg-min-max-stats-precision1 { + description + "Common nodes for recording average, minimum, and + maximum values for a statistic. These values all have + fraction-digits set to 1."; + + leaf avg { + type decimal64 { + fraction-digits 1; + } + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 1; + } + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 1; + } + description + "The maximum value of the statitic over the sampling + period"; + } + } + + grouping avg-min-max-instant-stats-precision1 { + description + "Common grouping for recording an instantaneous statistic value + in addition to avg-min-max stats"; + + leaf instant { + type decimal64 { + fraction-digits 1; + } + description + "The instantaneous value of the statistic."; + } + + uses avg-min-max-stats-precision1; + } + + grouping avg-min-max-instant-stats-precision2-dB { + description + "Common grouping for recording dB values with 2 decimal + precision. Values include the instantaneous, average, + minimum, and maximum statistics"; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The maximum value of the statistic over the sampling + period"; + } + } + + grouping avg-min-max-instant-stats-precision2-dBm { + description + "Common grouping for recording dBm values with 2 decimal + precision. Values include the instantaneous, average, + minimum, and maximum statistics"; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The maximum value of the statistic over the sampling + period"; + } + } + + grouping avg-min-max-instant-stats-precision2-mA { + description + "Common grouping for recording mA values with 2 decimal + precision. Values include the instantaneous, average, + minimum, and maximum statistics"; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The maximum value of the statistic over the sampling + period"; + } + } + + identity ADDRESS_FAMILY { + description + "A base identity for all address families"; + } + + identity IPV4 { + base ADDRESS_FAMILY; + description + "The IPv4 address family"; + } + + identity IPV6 { + base ADDRESS_FAMILY; + description + "The IPv6 address family"; + } + + identity MPLS { + base ADDRESS_FAMILY; + description + "The MPLS address family"; + } + + identity L2_ETHERNET { + base ADDRESS_FAMILY; + description + "The 802.3 Ethernet address family"; + } + +} diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-attributes.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-attributes.yang new file mode 100644 index 000000000..75eb15539 --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-attributes.yang @@ -0,0 +1,430 @@ +submodule openconfig-rib-bgp-attributes { + + belongs-to openconfig-rib-bgp { + prefix "oc-rib-bgp"; + } + + + // import some basic types + import ietf-inet-types { prefix inet; } + import openconfig-bgp-types { prefix oc-bgpt; } + import openconfig-extensions { prefix oc-ext; } + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This submodule contains common data definitions for BGP + attributes for use in BGP RIB tables."; + + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + + grouping bgp-as-path-attr-state { + description + "Data for representing BGP AS-PATH attribute"; + + leaf type { + type oc-bgpt:as-path-segment-type; + description + "The type of AS-PATH segment"; + } + + leaf-list member { + type inet:as-number; + description + "List of the AS numbers in the AS-PATH segment"; + } + } + + grouping bgp-as-path-attr-top { + description + "Top-level grouping for AS-PATH attribute data"; + + container as-path { + description + "Enclosing container for the list of AS path segments. + + In the Adj-RIB-In or Adj-RIB-Out, this list should show + the received or sent AS_PATH, respectively. For + example, if the local router is not 4-byte capable, this + value should consist of 2-octet ASNs or the AS_TRANS + (AS 23456) values received or sent in route updates. + + In the Loc-RIB, this list should reflect the effective + AS path for the route, e.g., a 4-octet value if the + local router is 4-octet capable."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4) + RFC 6793 - BGP Support for Four-octet AS Number Space + RFC 5065 - Autonomous System Confederations for BGP"; + + list segment { + description + "Unkeyed list of AS PATH segments"; + + container state { + config false; + description + "Opstate data for AS-PATH segments"; + + uses bgp-as-path-attr-state; + } + } + } + } + + grouping bgp-as4-path-attr-top { + description + "Top-level grouping for AS4-PATH attribute data"; + + container as4-path { + description + "This is the path encoded with 4-octet + AS numbers in the optional transitive AS4_PATH attribute. + This value is populated with the received or sent attribute + in Adj-RIB-In or Adj-RIB-Out, respectively. It should not + be populated in Loc-RIB since the Loc-RIB is expected to + store the effective AS-Path in the as-path leaf regardless + of being 4-octet or 2-octet."; + reference + "RFC 6793 - BGP Support for Four-octet AS Number Space"; + + list segment { + description + "Unkeyed list of AS PATH segments"; + + container state { + config false; + description + "Opstate data for AS-PATH segments"; + + uses bgp-as-path-attr-state; + } + } + } + } + + grouping bgp-community-attr-state { + description + "Common definition of BGP community attributes"; + + leaf-list community { + type union { + type oc-bgpt:bgp-well-known-community-type; + type oc-bgpt:bgp-std-community-type; + } + description + "List of standard or well-known BGP community + attributes."; + } + } + + grouping bgp-extended-community-attr-state { + description + "Common definition of BGP extended community attribute"; + + leaf-list ext-community { + type oc-bgpt:bgp-ext-community-recv-type; + description + "List of BGP extended community attributes. The received + extended community may be an explicitly modeled + type or unknown, represented by an 8-octet value + formatted according to RFC 4360."; + reference + "RFC 4360 - BGP Extended Communities Attribute"; + } + + } + + grouping bgp-aggregator-attr-state { + description + "Operational state data for the BGP aggregator + attribute"; + + leaf as { + type inet:as-number; + description + "AS number of the autnonomous system that performed the + aggregation."; + } + + leaf as4 { + type inet:as-number; + description + "AS number of the autnonomous system that performed the + aggregation (4-octet representation). This value is + populated if an upstream router is not 4-octet capable. + Its semantics are similar to the AS4_PATH optional + transitive attribute"; + reference + "RFC 6793 - BGP Support for Four-octet AS Number Space"; + } + + leaf address { + type inet:ipv4-address; + description + "IP address of the router that performed the + aggregation."; + } + } + + + grouping bgp-aggregator-attr-top { + description + "Common definition of the BGP aggregator attribute"; + + container aggregator { + description + "BGP attribute indicating the prefix has been aggregated by + the specified AS and router."; + + container state { + config false; + description + "Operational state data for BGP aggregator attribute"; + + uses bgp-aggregator-attr-state; + } + } + } + + grouping bgp-shared-common-attr-state { + description + "Route attributes shared across route table entries, + common to both LOC-Rib and Adj-RIB"; + + + leaf origin { + type oc-bgpt:bgp-origin-attr-type; + description + "BGP attribute defining the origin of the path information."; + } + + leaf atomic-aggregate { + type boolean; + description + "BGP attribute indicating that the prefix is an atomic + aggregate, i.e., the peer selected a less specific + route without selecting a more specific route that is + included in it."; + } + + leaf next-hop { + type inet:ip-address; + description + "BGP next hop attribute defining the IP address of the router + that should be used as the next hop to the destination"; + } + + leaf med { + type uint32; + description + "BGP multi-exit discriminator attribute used in BGP route + selection process"; + } + + leaf local-pref { + type uint32; + description + "BGP local preference attribute sent to internal peers to + indicate the degree of preference for externally learned + routes. The route with the highest local preference value + is preferred."; + } + + leaf originator-id { + type inet:ipv4-address; + description + "BGP attribute that provides the id as an IPv4 address + of the originator of the announcement."; + reference + "RFC 4456 - BGP Route Reflection: An Alternative to Full + Mesh Internal BGP (IBGP)"; + } + + leaf-list cluster-list { + type inet:ipv4-address; + description + "Represents the reflection path that the route has passed."; + reference + "RFC 4456 - BGP Route Reflection: An Alternative to Full + Mesh Internal BGP (IBGP)"; + } + + leaf aigp { + type uint64; + description + "BGP path attribute representing the accumulated IGP metric + for the path"; + reference + "RFC 7311 - The Accumulated IGP Metric Attribute for BGP"; + } + } + + grouping bgp-unknown-attr-flags-state { + description + "Operational state data for path attribute flags"; + + leaf optional { + type boolean; + description + "Defines whether the attribute is optional (if + set to true) or well-known (if set to false). + Set in the high-order bit of the BGP attribute + flags octet."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + leaf transitive { + type boolean; + description + "Defines whether an optional attribute is transitive + (if set to true) or non-transitive (if set to false). For + well-known attributes, the transitive flag MUST be set to + true. Set in the second high-order bit of the BGP attribute + flags octet."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + leaf partial { + type boolean; + description + "Defines whether the information contained in the optional + transitive attribute is partial (if set to true) or complete + (if set to false). For well-known attributes and for + optional non-transitive attributes, the partial flag + must be set to false. Set in the third high-order bit of + the BGP attribute flags octet."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + leaf extended { + type boolean; + description + "Defines whether the attribute length is one octet + (if set to false) or two octets (if set to true). Set in + the fourth high-order bit of the BGP attribute flags + octet."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + } + + grouping bgp-unknown-attr-state { + description + "Operational state data for path attributes not shared + across route entries, common to LOC-RIB and Adj-RIB"; + + leaf attr-type { + type uint8; + description + "1-octet value encoding the attribute type code"; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + leaf attr-len { + type uint16; + description + "One or two octet attribute length field indicating the + length of the attribute data in octets. If the Extended + Length attribute flag is set, the length field is 2 octets, + otherwise it is 1 octet"; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + + leaf attr-value { + type binary { + length 1..65535; + } + description + "Raw attribute value, not including the attribute + flags, type, or length. The maximum length + of the attribute value data is 2^16-1 per the max value + of the attr-len field (2 octets)."; + reference + "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)"; + } + } + + grouping bgp-unknown-attr-top { + description + "Unknown path attributes that are not expected to be shared + across route entries, common to LOC-RIB and Adj-RIB"; + + container unknown-attributes { + description + "Unknown path attributes that were received in the UPDATE + message which contained the prefix."; + + list unknown-attribute { + key "attr-type"; + description + "This list contains received attributes that are unrecognized + or unsupported by the local router. The list may be empty."; + + leaf attr-type { + type leafref { + path "../state/attr-type"; + } + description + "Reference to the list key"; + } + + container state { + description + "Operational state for unknown route attributes"; + + uses bgp-unknown-attr-flags-state; + uses bgp-unknown-attr-state; + } + } + } + } + + grouping bgp-loc-rib-attr-state { + description + "Path attributes that are not expected to be shared across + route entries, specific to LOC-RIB"; + + } + + grouping bgp-adj-rib-attr-state { + description + "Path attributes that are not expected to be shared across + route entries, specific to Adj-RIB"; + + leaf path-id { + type uint32; + description + "When the BGP speaker supports advertisement of multiple + paths for a prefix, the path identifier is used to + uniquely identify a route based on the combination of the + prefix and path id. In the Adj-RIB-In, the path-id value is + the value received in the update message. In the Loc-RIB, + if used, it should represent a locally generated path-id + value for the corresponding route. In Adj-RIB-Out, it + should be the value sent to a neighbor when add-paths is + used, i.e., the capability has been negotiated."; + reference + "draft-ietf-idr-add-paths - Advertisement of Multiple Paths + in BGP"; + } + } +} diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-ext.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-ext.yang new file mode 100644 index 000000000..3c7cf3535 --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-ext.yang @@ -0,0 +1,166 @@ +module openconfig-rib-bgp-ext { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/rib/bgp-ext"; + + prefix "oc-bgprib-ext"; + + import openconfig-rib-bgp { prefix oc-bgprib; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-rib-bgp-types { prefix oc-bgpribt; } + + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "Defines additional data nodes for the OpenConfig BGP RIB model. + These items reflect extensions that are desirable features but + are not currently supported in a majority of BGP + implementations."; + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + revision "2016-04-11" { + description + "OpenConfig public release"; + reference "0.2.0"; + } + + + grouping rib-ext-route-annotations { + description + "Extended annotations for routes in the routing tables"; + + leaf reject-reason { + type union { + type identityref { + base oc-bgpribt:BGP_NOT_SELECTED_BESTPATH; + } + type identityref { + base oc-bgpribt:BGP_NOT_SELECTED_POLICY; + } + } + description + "Indicates the reason the route is not used, either due to + policy filtering or bestpath selection"; + } + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv4-unicast/oc-bgprib:loc-rib/" + + "oc-bgprib:routes/oc-bgprib:route/oc-bgprib:state" { + description + "Add extended annotations to the Loc-RIB for IPv4"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv6-unicast/oc-bgprib:loc-rib/" + + "oc-bgprib:routes/oc-bgprib:route/oc-bgprib:state" { + description + "Add extended annotations to the Loc-RIB for IPv6"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv4-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-in-pre/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state" { + description + "Add extended annotations to Adj-RIB for IPv4"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv4-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-in-post/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv4"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv4-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-out-pre/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv4"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv4-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-out-post/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv4"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv6-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-in-pre/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv6"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv6-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-in-post/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv6"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv6-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-out-pre/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv6"; + + uses rib-ext-route-annotations; + } + + augment "/oc-bgprib:bgp-rib/oc-bgprib:afi-safis/" + + "oc-bgprib:afi-safi/oc-bgprib:ipv6-unicast/" + + "oc-bgprib:neighbors/oc-bgprib:neighbor/" + + "oc-bgprib:adj-rib-out-post/oc-bgprib:routes/oc-bgprib:route" + + "/oc-bgprib:state"{ + description + "Add extended annotations to Adj-RIB for IPv6"; + + uses rib-ext-route-annotations; + } + +} \ No newline at end of file diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-shared-attributes.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-shared-attributes.yang new file mode 100644 index 000000000..3a03b4032 --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-shared-attributes.yang @@ -0,0 +1,170 @@ +submodule openconfig-rib-bgp-shared-attributes { + + belongs-to openconfig-rib-bgp { + prefix "oc-rib-bgp"; + } + + + // import some basic types + import openconfig-extensions { prefix oc-ext; } + + include openconfig-rib-bgp-attributes; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This submodule contains structural data definitions for + attribute sets shared across routes."; + + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + + grouping attribute-sets-top { + description + "Top level grouping for list of common attribute sets"; + + container attr-sets { + description + "Enclosing container for the list of path attribute sets"; + + list attr-set { + key "index"; + + description + "List of path attributes that may be in use by multiple + routes in the table"; + + leaf index { + type leafref { + path "../state/index"; + } + description + "Reference to list key"; + } + + container state { + config false; + description + "Operational state for common path attributes"; + + leaf index { + type uint64; + description + "System generated index for each attribute set. The + index is used to reference an attribute set from a + specific path. Multiple paths may reference the same + attribute set."; + } + + uses bgp-shared-common-attr-state; + } + uses bgp-aggregator-attr-top; + uses bgp-as-path-attr-top; + uses bgp-as4-path-attr-top; + } + } + } + + grouping community-sets-top { + description + "Top level grouping for list of shared community attribute + sets"; + + container communities { + description + "Enclosing container for the list of community attribute + sets"; + + list community { + key "index"; + + description + "List of path attributes that may be in use by multiple + routes in the table"; + + leaf index { + type leafref { + path "../state/index"; + } + description + "Reference to the list key"; + } + + container state { + config false; + description + "Operational state for shared BGP community attribute"; + + leaf index { + type uint64; + description + "System generated index for each attribute set. The + index is used to reference an attribute set from a + specific path. Multiple paths may reference the same + attribute set."; + } + + uses bgp-community-attr-state; + } + } + } + } + + grouping ext-community-sets-top { + description + "Top level grouping for list of extended community attribute + sets"; + + container ext-communities { + description + "Enclosing container for the list of extended community + attribute sets"; + + list ext-community { + key "index"; + + description + "List of path attributes that may be in use by multiple + routes in the table"; + + leaf index { + type leafref { + path "../state/index"; + } + description + "Reference to the list key"; + } + + container state { + config false; + description + "Operational state for shared BGP extended community + attribute"; + + leaf index { + type uint64; + description + "System generated index for each attribute set. The + index is used to reference an attribute set from a + specific path. Multiple paths may reference the same + attribute set."; + } + + uses bgp-extended-community-attr-state; + } + } + } + } +} diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-table-attributes.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-table-attributes.yang new file mode 100644 index 000000000..285f0a9bb --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-table-attributes.yang @@ -0,0 +1,113 @@ +submodule openconfig-rib-bgp-table-attributes { + + belongs-to openconfig-rib-bgp { + prefix "oc-rib-bgp"; + } + + + // import some basic types + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + import openconfig-rib-bgp-types { prefix oc-bgpribt; } + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This submodule contains common data definitions for data + related to a RIB entry, or RIB table."; + + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + + + grouping bgp-common-route-annotations-state { + description + "Data definitions for flags and other information attached + to routes in both LOC-RIB and Adj-RIB"; + + leaf last-modified { + type oc-types:timeticks64; + description + "Timestamp when this path was last modified. + + The value is the timestamp in seconds relative to + the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf valid-route { + type boolean; + description + "Indicates that the route is considered valid by the + local router"; + } + + leaf invalid-reason { + type identityref { + base oc-bgpribt:INVALID_ROUTE_REASON; + } + description + "If the route is rejected as invalid, this indicates the + reason."; + } + + } + + grouping bgp-loc-rib-route-annotations-state { + description + "Data definitions for information attached to routes in the + LOC-RIB"; + + // placeholder for route metadata specific to the LOC-RIB + + } + + grouping bgp-adj-rib-in-post-route-annotations-state { + description + "Data definitions for information attached to routes in the + Adj-RIB-in post-policy table"; + + leaf best-path { + type boolean; + description + "Current path was selected as the best path."; + } + } + + grouping bgp-common-table-attrs-state { + description + "Common attributes attached to all routing tables"; + + // placeholder for metadata associated with all tables + } + + grouping bgp-common-table-attrs-top { + description + "Operational state data for common attributes attached to + all routing tables"; + // no enclosing container as this data will fit under an + // existing LOC-RIB container + + container state { + config false; + description + "Operational state data for data related to the entire + LOC-RIB"; + + uses bgp-common-table-attrs-state; + } + } + + +} \ No newline at end of file diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-tables.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-tables.yang new file mode 100644 index 000000000..6ca14b445 --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-tables.yang @@ -0,0 +1,646 @@ +submodule openconfig-rib-bgp-tables { + + belongs-to openconfig-rib-bgp { + prefix "oc-rib-bgp"; + } + + + // import some basic types + import ietf-inet-types { prefix inet; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-policy-types { prefix oc-pol-types; } + + include openconfig-rib-bgp-attributes; + include openconfig-rib-bgp-shared-attributes; + include openconfig-rib-bgp-table-attributes; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This submodule contains structural data definitions for + BGP routing tables."; + + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + + grouping bgp-adj-rib-common-attr-refs { + description + "Definitions of common references to attribute sets for + multiple AFI-SAFIs for Adj-RIB tables"; + + leaf attr-index { + type leafref { + path "../../../../../../../../../../attr-sets/attr-set/" + + "state/index"; + } + description + "Reference to the common attribute group for the + route"; + } + + leaf community-index { + type leafref { + path "../../../../../../../../../../communities/community/" + + "state/index"; + } + description + "Reference to the community attribute for the route"; + } + + leaf ext-community-index { + type leafref { + path "../../../../../../../../../../ext-communities/" + + "ext-community/state/index"; + } + description + "Reference to the extended community attribute for the + route"; + } + } + + grouping bgp-loc-rib-common-attr-refs { + description + "Definitions of common references to attribute sets for + multiple AFI-SAFIs for LOC-RIB tables"; + + leaf attr-index { + type leafref { + path "../../../../../../../../attr-sets/attr-set/" + + "state/index"; + } + description + "Reference to the common attribute group for the + route"; + } + + leaf community-index { + type leafref { + path "../../../../../../../../communities/community/" + + "state/index"; + } + description + "Reference to the community attribute for the route"; + } + + leaf ext-community-index { + type leafref { + path "../../../../../../../../ext-communities/" + + "ext-community/state/index"; + } + description + "Reference to the extended community attribute for the + route"; + } + } + + grouping bgp-loc-rib-common-keys { + description + "Common references used in keys for IPv4 and IPv6 + LOC-RIB entries"; + + leaf origin { + type union { + type inet:ip-address-no-zone; + type identityref { + base oc-pol-types:INSTALL_PROTOCOL_TYPE; + } + } + description + "Indicates the origin of the route. If the route is learned + from a neighbor, this value is the neighbor address. If + the route was injected or redistributed from another + protocol, the origin indicates the source protocol for the + route."; + } + + leaf path-id { + type uint32; + default 0; + description + "If the route is learned from a neighbor, the path-id + corresponds to the path-id for the route in the + corresponding adj-rib-in-post table. If the route is + injected from another protocol, or the neighbor does not + support BGP add-paths, the path-id should be set + to zero, also the default value."; + } + } + + grouping bgp-loc-rib-key-refs { + description + "Key references to support operational state structure for + the BGP LOC-RIB table"; + + leaf prefix { + type leafref { + path "../state/prefix"; + } + description + "Reference to the prefix list key"; + } + + leaf origin { + type leafref { + path "../state/origin"; + } + description + "Reference to the origin list key"; + } + + leaf path-id { + type leafref { + path "../state/path-id"; + } + description + "Reference to the path-id list key"; + } + } + + grouping ipv4-loc-rib-top { + description + "Top-level grouping for IPv4 routing tables"; + + container loc-rib { + config false; + description + "Container for the IPv4 BGP LOC-RIB data"; + + uses bgp-common-table-attrs-top; + + container routes { + description + "Enclosing container for list of routes in the routing + table."; + + list route { + key "prefix origin path-id"; + + description + "List of routes in the table, keyed by the route + prefix, the route origin, and path-id. The route + origin can be either the neighbor address from which + the route was learned, or the source protocol that + injected the route. The path-id distinguishes routes + for the same prefix received from a neighbor (e.g., + if add-paths is eanbled)."; + + uses bgp-loc-rib-key-refs; + + container state { + description + "Operational state data for route entries in the + BGP LOC-RIB"; + + leaf prefix { + type inet:ipv4-prefix; + description + "The IPv4 prefix corresponding to the route"; + } + + uses bgp-loc-rib-common-keys; + + uses bgp-loc-rib-common-attr-refs; + + uses bgp-loc-rib-attr-state; + + uses bgp-common-route-annotations-state; + uses bgp-loc-rib-route-annotations-state; + + } + + uses bgp-unknown-attr-top; + + } + } + } + } + + + grouping ipv6-loc-rib-top { + description + "Top-level grouping for IPv6 routing tables"; + + container loc-rib { + config false; + description + "Container for the IPv6 BGP LOC-RIB data"; + + uses bgp-common-table-attrs-top; + + + container routes { + description + "Enclosing container for list of routes in the routing + table."; + + list route { + key "prefix origin path-id"; + + description + "List of routes in the table, keyed by the route + prefix, the route origin, and path-id. The route + origin can be either the neighbor address from which + the route was learned, or the source protocol that + injected the route. The path-id distinguishes routes + for the same prefix received from a neighbor (e.g., + if add-paths is eanbled)."; + + uses bgp-loc-rib-key-refs; + + container state { + description + "Operational state data for route entries in the + BGP LOC-RIB"; + + leaf prefix { + type inet:ipv6-prefix; + description + "The IPv6 prefix corresponding to the route"; + } + + uses bgp-loc-rib-common-keys; + + uses bgp-loc-rib-common-attr-refs; + + uses bgp-loc-rib-attr-state; + + uses bgp-common-route-annotations-state; + uses bgp-loc-rib-route-annotations-state; + + } + + uses bgp-unknown-attr-top; + } + } + } + } + + grouping bgp-adj-rib-key-refs { + description + "Key references to support operational state structure for + the BGP Adj-RIB tables"; + + leaf prefix { + type leafref { + path "../state/prefix"; + } + description + "Reference to the prefix list key"; + } + + leaf path-id { + type leafref { + path "../state/path-id"; + } + description + "Reference to the path-id list key"; + } + } + + grouping ipv4-adj-rib-common { + description + "Common structural grouping for each IPv4 adj-RIB table"; + + uses bgp-common-table-attrs-top; + + container routes { + config false; + description + "Enclosing container for list of routes in the routing + table."; + + list route { + key "prefix path-id"; + + description + "List of routes in the table, keyed by a combination of + the route prefix and path-id to distinguish multiple + routes received from a neighbor for the same prefix, + e.g., when BGP add-paths is enabled."; + + uses bgp-adj-rib-key-refs; + + container state { + description + "Operational state data for BGP Adj-RIB entries"; + + leaf prefix { + type inet:ipv4-prefix; + description + "Prefix for the route"; + } + + uses bgp-adj-rib-attr-state; + + uses bgp-adj-rib-common-attr-refs; + + uses bgp-common-route-annotations-state; + } + + uses bgp-unknown-attr-top; + + } + } + } + + grouping ipv4-adj-rib-in-post { + description + "Common structural grouping for the IPv4 adj-rib-in + post-policy table"; + + uses bgp-common-table-attrs-top; + + container routes { + config false; + description + "Enclosing container for list of routes in the routing + table."; + + list route { + key "prefix path-id"; + + description + "List of routes in the table, keyed by a combination of + the route prefix and path-id to distinguish multiple + routes received from a neighbor for the same prefix, + e.g., when BGP add-paths is enabled."; + + uses bgp-adj-rib-key-refs; + + container state { + description + "Operational state data for BGP Adj-RIB entries"; + + leaf prefix { + type inet:ipv4-prefix; + description + "Prefix for the route"; + } + + uses bgp-adj-rib-attr-state; + + uses bgp-adj-rib-common-attr-refs; + + uses bgp-common-route-annotations-state; + + uses bgp-adj-rib-in-post-route-annotations-state; + } + + uses bgp-unknown-attr-top; + } + } + } + + + grouping ipv4-adj-rib-top { + description + "Top-level grouping for Adj-RIB table"; + + container neighbors { + config false; + description + "Enclosing container for neighbor list"; + + list neighbor { + key "neighbor-address"; + description + "List of neighbors (peers) of the local BGP speaker"; + + leaf neighbor-address { + type leafref { + path "../state/neighbor-address"; + } + description + "Reference to the list key"; + } + + container state { + description + "Operational state for each neighbor BGP Adj-RIB"; + + leaf neighbor-address { + type inet:ip-address-no-zone; + description + "IP address of the BGP neighbor or peer"; + } + } + + container adj-rib-in-pre { + description + "Per-neighbor table containing the NLRI updates + received from the neighbor before any local input + policy rules or filters have been applied. This can + be considered the 'raw' updates from the neighbor."; + + uses ipv4-adj-rib-common; + + } + + container adj-rib-in-post { + description + "Per-neighbor table containing the paths received from + the neighbor that are eligible for best-path selection + after local input policy rules have been applied."; + + uses ipv4-adj-rib-in-post; + } + + container adj-rib-out-pre { + description + "Per-neighbor table containing paths eligble for + sending (advertising) to the neighbor before output + policy rules have been applied"; + + uses ipv4-adj-rib-common; + + } + + container adj-rib-out-post { + description + "Per-neighbor table containing paths eligble for + sending (advertising) to the neighbor after output + policy rules have been applied"; + + uses ipv4-adj-rib-common; + + } + } + } + } + + grouping ipv6-adj-rib-common { + description + "Common structural grouping for each IPv6 adj-RIB table"; + + uses bgp-common-table-attrs-state; + + container routes { + config false; + description + "Enclosing container for list of routes in the routing + table."; + + list route { + key "prefix path-id"; + + description + "List of routes in the table"; + + uses bgp-adj-rib-key-refs; + + container state { + description + "Operational state data for BGP Adj-RIB entries"; + + leaf prefix { + type inet:ipv6-prefix; + description + "Prefix for the route"; + } + + uses bgp-adj-rib-attr-state; + + uses bgp-adj-rib-common-attr-refs; + + uses bgp-common-route-annotations-state; + } + + uses bgp-unknown-attr-top; + } + } + } + + grouping ipv6-adj-rib-in-post { + description + "Common structural grouping for the IPv6 adj-rib-in + post-policy table"; + + uses bgp-common-table-attrs-state; + + container routes { + config false; + description + "Enclosing container for list of routes in the routing + table."; + + list route { + key "prefix path-id"; + + description + "List of routes in the table"; + + uses bgp-adj-rib-key-refs; + + container state { + description + "Operational state data for BGP Adj-RIB entries"; + + leaf prefix { + type inet:ipv6-prefix; + description + "Prefix for the route"; + } + + uses bgp-adj-rib-attr-state; + + uses bgp-adj-rib-common-attr-refs; + + uses bgp-common-route-annotations-state; + + uses bgp-adj-rib-in-post-route-annotations-state; + } + + uses bgp-unknown-attr-top; + } + } + } + + grouping ipv6-adj-rib-top { + description + "Top-level grouping for Adj-RIB table"; + + container neighbors { + config false; + description + "Enclosing container for neighbor list"; + + list neighbor { + key "neighbor-address"; + description + "List of neighbors (peers) of the local BGP speaker"; + + leaf neighbor-address { + type leafref { + path "../state/neighbor-address"; + } + description + "Reference to the list key"; + } + + container state { + description + "Operational state for each neighbor BGP Adj-RIB"; + + leaf neighbor-address { + type inet:ip-address-no-zone; + description + "IP address of the BGP neighbor or peer"; + } + } + + container adj-rib-in-pre { + description + "Per-neighbor table containing the NLRI updates + received from the neighbor before any local input + policy rules or filters have been applied. This can + be considered the 'raw' updates from the neighbor."; + + uses ipv6-adj-rib-common; + + } + + container adj-rib-in-post { + description + "Per-neighbor table containing the paths received from + the neighbor that are eligible for best-path selection + after local input policy rules have been applied."; + + uses ipv6-adj-rib-in-post; + } + + container adj-rib-out-pre { + description + "Per-neighbor table containing paths eligble for + sending (advertising) to the neighbor before output + policy rules have been applied"; + + uses ipv6-adj-rib-common; + + } + + container adj-rib-out-post { + description + "Per-neighbor table containing paths eligble for + sending (advertising) to the neighbor after output + policy rules have been applied"; + + uses ipv6-adj-rib-common; + + } + } + } + } + +} \ No newline at end of file diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-types.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-types.yang new file mode 100644 index 000000000..8758cead0 --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp-types.yang @@ -0,0 +1,155 @@ +module openconfig-rib-bgp-types { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/rib/bgp-types"; + + prefix "oc-bgprib-types"; + + import openconfig-extensions { prefix oc-ext; } + + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "Defines identity and type defintions associated with + the OpenConfig BGP RIB modules"; + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + revision "2016-04-11" { + description + "OpenConfig public release"; + reference "0.2.0"; + } + + identity INVALID_ROUTE_REASON { + description + "Base identity for reason code for routes that are rejected as + invalid. Some derived entities are based on BMP v3"; + reference "BGP Monitoring Protocol (draft-ietf-grow-bmp-07)"; + } + + identity INVALID_CLUSTER_LOOP { + base INVALID_ROUTE_REASON; + description + "Route was invalid due to CLUSTER_LIST loop"; + } + + identity INVALID_AS_LOOP { + base INVALID_ROUTE_REASON; + description + "Route was invalid due to AS_PATH loop"; + } + + identity INVALID_ORIGINATOR { + base INVALID_ROUTE_REASON; + description + "Route was invalid due to ORIGINATOR_ID, e.g., update has + local router as originator"; + } + + identity INVALID_CONFED { + base INVALID_ROUTE_REASON; + description + "Route was invalid due to a loop in the AS_CONFED_SEQUENCE or + AS_CONFED_SET attributes"; + } + + identity BGP_NOT_SELECTED_BESTPATH { + description + "Base identity for indicating reason a route was was not + selected by BGP route selection algorithm"; + reference + "RFC 4271 - Section 9.1"; + } + + identity LOCAL_PREF_LOWER { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route has a lower localpref attribute than current best path"; + reference + "RFC 4271 - Section 9.1.2"; + } + + identity AS_PATH_LONGER { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route has a longer AS path attribute than current best path"; + reference + "RFC 4271 - Section 9.1.2.2 (a)"; + } + + identity ORIGIN_TYPE_HIGHER { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route has a higher origin type, i.e., IGP origin is preferred + over EGP or incomplete"; + reference + "RFC 4271 - Section 9.1.2.2 (b)"; + } + + identity MED_HIGHER { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route has a higher MED, or metric, attribute than the current + best path"; + reference + "RFC 4271 - Section 9.1.2.2 (c)"; + } + + identity PREFER_EXTERNAL { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route source is via IGP, rather than EGP."; + reference + "RFC 4271 - Section 9.1.2.2 (d)"; + } + + identity NEXTHOP_COST_HIGHER { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route has a higher interior cost to the next hop."; + reference + "RFC 4271 - Section 9.1.2.2 (e)"; + } + + identity HIGHER_ROUTER_ID { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route was sent by a peer with a higher BGP Identifier value, + or router id"; + reference + "RFC 4271 - Section 9.1.2.2 (f)"; + } + + identity HIGHER_PEER_ADDRESS { + base BGP_NOT_SELECTED_BESTPATH; + description + "Route was sent by a peer with a higher IP address"; + reference + "RFC 4271 - Section 9.1.2.2 (g)"; + } + + identity BGP_NOT_SELECTED_POLICY { + description + "Base identity for reason code for routes that are rejected + due to policy"; + } + + identity REJECTED_IMPORT_POLICY { + base BGP_NOT_SELECTED_POLICY; + description + "Route was rejected after apply import policies"; + } +} \ No newline at end of file diff --git a/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp.yang b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp.yang new file mode 100644 index 000000000..1af876b40 --- /dev/null +++ b/demo/protobuf_getting_started/yang/rib/openconfig-rib-bgp.yang @@ -0,0 +1,183 @@ +module openconfig-rib-bgp { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/rib/bgp"; + + prefix "oc-rib-bgp"; + + // import some basic types + import openconfig-bgp-types { prefix oc-bgpt; } + import openconfig-extensions { prefix oc-ext; } + + // include RIB submodules + + // structure for LOC-RIB and Adj-RIB tables + include openconfig-rib-bgp-tables; + + // structure of shared attribute groups + include openconfig-rib-bgp-shared-attributes; + + // groupings of attributes in three categories: + // - shared across multiple routes + // - common to LOC-RIB and Adj-RIB, but not shared across routes + // - specific to LOC-RIB or Adj-RIB + include openconfig-rib-bgp-attributes; + + // groupings of annotations for each route or table + include openconfig-rib-bgp-table-attributes; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "Defines a data model for representing BGP routing table (RIB) + contents. The model supports 5 logical RIBs per address family: + + loc-rib: This is the main BGP routing table for the local routing + instance, containing best-path selections for each prefix. The + loc-rib table may contain multiple routes for a given prefix, + with an attribute to indicate which was selected as the best + path. Note that multiple paths may be used or advertised even if + only one path is marked as best, e.g., when using BGP + add-paths. An implementation may choose to mark multiple + paths in the RIB as best path by setting the flag to true for + multiple entries. + + adj-rib-in-pre: This is a per-neighbor table containing the NLRI + updates received from the neighbor before any local input policy + rules or filters have been applied. This can be considered the + 'raw' updates from a given neighbor. + + adj-rib-in-post: This is a per-neighbor table containing the + routes received from the neighbor that are eligible for + best-path selection after local input policy rules have been + applied. + + adj-rib-out-pre: This is a per-neighbor table containing routes + eligible for sending (advertising) to the neighbor before output + policy rules have been applied. + + adj-rib-out-post: This is a per-neighbor table containing routes + eligible for sending (advertising) to the neighbor after output + policy rules have been applied."; + + oc-ext:openconfig-version "0.3.0"; + + revision "2016-10-17" { + description + "OpenConfig BGP RIB refactor"; + reference "0.3.0"; + } + + revision "2016-04-11" { + description + "OpenConfig public release"; + reference "0.2.0"; + } + + + + // grouping statements + + + + grouping bgp-rib-state { + description + "Operational state data for the top level BGP RIB"; + + leaf afi-safi-name { + type identityref { + base oc-bgpt:AFI_SAFI_TYPE; + } + description "AFI,SAFI"; + } + } + + grouping bgp-rib-top { + description + "Top-level grouping for the BGP RIB"; + + container bgp-rib { + config false; + description + "Top level container for BGP RIBs"; + + uses attribute-sets-top; + uses community-sets-top; + uses ext-community-sets-top; + + container afi-safis { + config false; + description + "Enclosing container for address family list"; + + list afi-safi { + key "afi-safi-name"; + description + "list of afi-safi types"; + + leaf afi-safi-name { + type leafref { + path "../state/afi-safi-name"; + } + description + "Reference to the list key"; + } + + container state { + config false; + description + "Operational state data for the BGP list"; + + uses bgp-rib-state; + } + + container ipv4-unicast { + when "../afi-safi-name = 'oc-bgpt:IPV4_UNICAST'" { + description + "Include this container for IPv4 unicast RIB"; + } + description + "Routing tables for IPv4 unicast -- active when the + afi-safi name is ipv4-unicast"; + + uses ipv4-loc-rib-top; + uses ipv4-adj-rib-top; + } + + container ipv6-unicast { + when "../afi-safi-name = 'oc-bgpt:IPV6_UNICAST'" { + description + "Include this container for IPv6 unicast RIB"; + } + description + "Routing tables for IPv6 unicast -- active when the + afi-safi name is ipv6-unicast"; + + uses ipv6-loc-rib-top; + uses ipv6-adj-rib-top; + } + } + } + } + } + + + // data definition statements + + uses bgp-rib-top; + + // augment statements + + + // rpc statements + + // notification statements + +} diff --git a/docs/protobuf_getting_started.md b/docs/protobuf_getting_started.md new file mode 100644 index 000000000..11df0f30e --- /dev/null +++ b/docs/protobuf_getting_started.md @@ -0,0 +1,153 @@ +# Using ygot To Generate a Protobuf Representation of a YANG Schema +**Author**: robjs +**Date**: October 2017 + +There are a number of cases in which a protobuf representation of a YANG schema is useful. Particularly: + +* Where there is no native language binding generator for the language. Whilst [ygot](https://github.com/openconfig/ygot) and [pyangbind](https://github.com/robshakir/pyangbind) provide solutions for Go and Python respectively, there are limited toolkits for other languages. Use of a protobuf schema allows usable code artefacts to be generated through use of `protoc`. Protobuf supports a number of languages both [natively](https://developers.google.com/protocol-buffers/docs/reference/overview) and via [third-party plugins](https://github.com/google/protobuf/blob/master/docs/third_party.md). +* Where efficient on-the-wire encoding is required. Protobuf can be serialised efficiently to an [binary format](https://developers.google.com/protocol-buffers/docs/encoding) resulting in significantly lower data volumes than other encodings (e.g., XML, JSON). + +To allow these two use cases to be met, [ygot](https://github.com/openconfig/ygot) implements transformation of a YANG schema to a set of protobuf messages. The design choices made for this transformation are described [in this document](https://github.com/openconfig/ygot/blob/master/docs/yang-to-protobuf-transformations-spec.md). + +This document provides some background as to how to generate a Protobuf definition from a YANG schema. Using the [OpenConfig BGP RIB model](https://github.com/openconfig/public/tree/master/release/models/rib) as an example. + +## Understanding the Output Protobuf Files + +### Filesystem Hierarchy + +The `ygot` package contains a `proto_generator` binary ([source](https://github.com/openconfig/ygot/tree/master/proto_generator)). This binary is used to generate the protocol buffer definitions. Rather than outputting an individual protobuf file with all message definitions within it, the generate outputs a hierarchy of files following the schema of the YANG module that is supplied. + +For example, with the following YANG module: + +```yang +module simple { + namespace "urn:s"; + prefix "s"; + + container a { + container b { + container c { + leaf d { type string; } + } + } + + container e { + leaf f { type string; } + } + } +} +``` + +The following file hierarchy is output: + +``` +/ +//simple +//simple/a +//simple/a/a.proto +//simple/a/b +//simple/a/b/b.proto +//simple/simple.proto +``` + +The three generated protobuf files (`simple.proto`, `a.proto` and `b.proto`) contain the children of the element that they are named after. Therefore `a.proto` contains definitions for the schema element `/a/b`, `b.proto` contains definitions for `/a/b/c` (and `d` since it is contained within `c` and does not generate a protobuf `message`). + +In the filesystem hierarchy `` is a directory name specified using the `output_dir` flag of the `proto_generator` binary. The `` is specified using the `package_name` flag, and indicates the base package name that should be used for the generated protobuf file definitions. + +In order to comply with constraints of some build systems (particularly `go build`), one protobuf `package` is output per filesystem directory. This allows generated code for each package to be within its own directory, and hence build systems that require packages to have a one-to-one mapping between packages and filesystem directories to be used. + +### Protobuf File Contents + +If we examine an individual `proto`, for example, `simple.proto`, trimming the header the contents are as follows: + +```protobuf +syntax = "proto3"; + +package .simple; + +import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; +import "github.com/openconfig/ygot/proto/yext/yext.proto"; +import "///simple/a/a.proto"; + +// A represents the /simple/a YANG schema element. +message A { + a.B b = 367480893 [(yext.schemapath) = "/a/b"]; + a.E e = 367480890 [(yext.schemapath) = "/a/e"]; +} +``` + +Each `package` is named according to the base package name specified as the `package_name` flag. By default, this name is specified to be `openconfig`. There are two dependent protobuf files imported: + + * `ywrapper.proto` provides a set of wrapper messages for basic protobuf types, allowing a caller to be able to distinguish whether a field was set. The path to `ywrapper.proto` can be modified using the `ywrapper_path` command-line flag. + * `yext.proto` provides a set of extensions to the base protobuf descriptors to be able to add YANG-specific annotations. This is used to annotate schema paths (e.g., the `/a/b` annotation in the example above), and information relating to YANG identifiers (e.g., enumerated value names) to the output protobuf. + +Both `yext.proto` and `ywrapper.proto` default to being imported from the `ygot` GitHub repository. + +The package then imports any child packages which define its children. In this example, since the YANG container `a` has children `b` and `e`, the `a.proto` which defines the *children* of `a` is imported. The path to this import consists of a number of parts: + +* `` -- this path is specified through the `base_import_path` flag. It specifies the path that should be used to search for imports. This can be used to set the output directory to some relative path to a particular import path that is supplied to `protoc`. +* `` and ` 0 { // Sort the set of enumerations so that they are deterministically output. sort.Strings(protoEnums) - fp := []string{basePackageName, fmt.Sprintf("%s.proto", enumPackageName)} + fp := []string{basePackageName, enumPackageName, fmt.Sprintf("%s.proto", enumPackageName)} genProto.Packages[fmt.Sprintf("%s.%s", basePackageName, enumPackageName)] = Proto3Package{ FilePath: fp, Enums: protoEnums, } - } for _, n := range msgPaths { diff --git a/ygen/gogen.go b/ygen/gogen.go index e118addb8..d11dffb25 100644 --- a/ygen/gogen.go +++ b/ygen/gogen.go @@ -684,7 +684,6 @@ func makeTemplate(name, src string) *template.Template { // DefaultYgotImportPath, and an unset cfg.GoOptions.YtypesImportPath results in the // path for ytypes being set to DefaultYtypesImportPath. func writeGoHeader(yangFiles, includePaths []string, cfg GeneratorConfig) (string, error) { - // Determine the running binary's name. if cfg.Caller == "" { cfg.Caller = callerName() diff --git a/ygen/protoelements.go b/ygen/protoelements.go index 42bc38593..334e070d0 100644 --- a/ygen/protoelements.go +++ b/ygen/protoelements.go @@ -65,6 +65,8 @@ func (s *genState) yangTypeToProtoType(args resolveTypeArgs, pargs resolveProtoT return &mappedType{nativeType: "ywrapper.IntValue"}, nil case yang.Yuint8, yang.Yuint16, yang.Yuint32, yang.Yuint64: return &mappedType{nativeType: "ywrapper.UintValue"}, nil + case yang.Ybinary: + return &mappedType{nativeType: "ywrapper.BytesValue"}, nil case yang.Ybool, yang.Yempty: return &mappedType{nativeType: "ywrapper.BoolValue"}, nil case yang.Ystring: @@ -133,6 +135,8 @@ func (s *genState) yangTypeToProtoScalarType(args resolveTypeArgs, pargs resolve return &mappedType{nativeType: "sint64"}, nil case yang.Yuint8, yang.Yuint16, yang.Yuint32, yang.Yuint64: return &mappedType{nativeType: "uint64"}, nil + case yang.Ybinary: + return &mappedType{nativeType: "bytes"}, nil case yang.Ybool, yang.Yempty: return &mappedType{nativeType: "bool"}, nil case yang.Ystring: diff --git a/ygen/protoelements_test.go b/ygen/protoelements_test.go index ef51e16db..2c72fc635 100644 --- a/ygen/protoelements_test.go +++ b/ygen/protoelements_test.go @@ -83,6 +83,11 @@ func TestYangTypeToProtoType(t *testing.T) { in: []resolveTypeArgs{{yangType: &yang.YangType{Kind: yang.Ystring}}}, wantWrapper: &mappedType{nativeType: "ywrapper.StringValue"}, wantScalar: &mappedType{nativeType: "string"}, + }, { + name: "binary", + in: []resolveTypeArgs{{yangType: &yang.YangType{Kind: yang.Ybinary}}}, + wantWrapper: &mappedType{nativeType: "ywrapper.BytesValue"}, + wantScalar: &mappedType{nativeType: "bytes"}, }, { name: "decimal64", in: []resolveTypeArgs{{yangType: &yang.YangType{Kind: yang.Ydecimal64}}}, @@ -91,7 +96,6 @@ func TestYangTypeToProtoType(t *testing.T) { }, { name: "unmapped types", in: []resolveTypeArgs{ - {yangType: &yang.YangType{Kind: yang.Ybinary}}, {yangType: &yang.YangType{Kind: yang.Ybits}}, }, wantErr: true, diff --git a/ygen/protogen.go b/ygen/protogen.go index 9ca7ffdd0..72f2412f9 100644 --- a/ygen/protogen.go +++ b/ygen/protogen.go @@ -31,9 +31,8 @@ const ( // protoAnyType is the name of the type to use for a google.protobuf.Any field. protoAnyType = "google.protobuf.Any" // protoAnyPackage is the name of the import to be used when a google.protobuf.Any field - // is included in the output data. The string specified has .proto appended to it when - // output. - protoAnyPackage = "google/protobuf/any" + // is included in the output data. + protoAnyPackage = "google/protobuf/any.proto" // protoListKeyMessageSuffix specifies the suffix that should be added to a list's name // to specify the repeated message that makes up the list's key. The repeated message is // called . @@ -140,7 +139,7 @@ package {{ .PackageName }}; import "{{ .YwrapperPath }}/ywrapper.proto"; import "{{ .YextPath }}/yext.proto"; {{- range $importedProto := .Imports }} -import "{{ $importedProto }}.proto"; +import "{{ $importedProto }}"; {{- end }} ` @@ -385,12 +384,13 @@ func genProto3Msg(msg *yangDirectory, msgs map[string]*yangDirectory, state *gen switch { case field.IsList(): - fieldType, keyMsg, err := protoListDefinition(protoDefinitionArgs{ + listDef, keyMsg, err := protoListDefinition(protoDefinitionArgs{ field: field, definedDirectories: msgs, state: state, compressPaths: cfg.compressPaths, basePackageName: cfg.basePackageName, + enumPackageName: cfg.enumPackageName, baseImportPath: cfg.baseImportPath, annotateSchemaPaths: cfg.annotateSchemaPaths, annotateEnumNames: cfg.annotateEnumNames, @@ -405,7 +405,10 @@ func genProto3Msg(msg *yangDirectory, msgs map[string]*yangDirectory, state *gen if keyMsg != nil { msgDefs = append(msgDefs, *keyMsg) } - fieldDef.Type = fieldType + + fieldDef.Type = listDef.listType + addNewKeys(imports, listDef.imports) + // Lists are always repeated fields. fieldDef.IsRepeated = true case field.IsContainer(): @@ -421,7 +424,7 @@ func genProto3Msg(msg *yangDirectory, msgs map[string]*yangDirectory, state *gen // Add the import to the slice of imports if it is not already // there. This allows the message file to import the required // child packages. - childpath := filepath.Join(cfg.baseImportPath, cfg.basePackageName, strings.Replace(childpkg, ".", "/", -1)) + childpath := importPath(cfg.baseImportPath, cfg.basePackageName, childpkg) if _, ok := imports[childpath]; !ok { imports[childpath] = true } @@ -467,7 +470,7 @@ func genProto3Msg(msg *yangDirectory, msgs map[string]*yangDirectory, state *gen // Add the global enumeration package if it is referenced by this field. if d.globalEnum { - imports[filepath.Join(cfg.baseImportPath, cfg.basePackageName, cfg.enumPackageName)] = true + imports[importPath(cfg.baseImportPath, cfg.basePackageName, cfg.enumPackageName)] = true } if field.ListAttr != nil { @@ -639,28 +642,39 @@ func genProtoEnum(field *yang.Entry, annotateEnumNames bool) (*protoMsgEnum, err return &protoMsgEnum{Values: eval}, nil } +// protoMsgListField describes a list field within a protobuf mesage. +type protoMsgListField struct { + listType string // listType is the name of the message that represents a list member. + imports []string // imports is the set of modules that are required by this list message. +} + // protoListDefinition takes an input field described by a yang.Entry, the generator context (the set of proto messages, and the generator -// state), along with whether path compression is enabled and generates the proto message definition for the list. It returns the type -// that the field within the parent should be mapped to, and an optional key proto definition (in the case of keyed lists). -func protoListDefinition(args protoDefinitionArgs) (string, *protoMsg, error) { +// state), along with whether path compression is enabled and generates the proto message definition for the list. It returns the definition +// of the field representing the list as a protoMsgListField and an optional message which stores the key of a keyed list. +func protoListDefinition(args protoDefinitionArgs) (*protoMsgListField, *protoMsg, error) { listMsg, ok := args.definedDirectories[args.field.Path()] if !ok { - return "", nil, fmt.Errorf("proto: could not resolve list %s into a defined message", args.field.Path()) + return nil, nil, fmt.Errorf("proto: could not resolve list %s into a defined message", args.field.Path()) } listMsgName, ok := args.state.uniqueDirectoryNames[args.field.Path()] if !ok { - return "", nil, fmt.Errorf("proto: could not find unique message name for %s", args.field.Path()) + return nil, nil, fmt.Errorf("proto: could not find unique message name for %s", args.field.Path()) } childPkg := args.state.protobufPackage(listMsg.entry, args.compressPaths) - var fieldType string var listKeyMsg *protoMsg + var listDef *protoMsgListField if !isKeyedList(listMsg.entry) { // In proto3 we represent unkeyed lists as a // repeated field of the parent message. - fieldType = fmt.Sprintf("%s.%s.%s", args.basePackageName, childPkg, listMsgName) + p := fmt.Sprintf("%s.%s.%s", args.basePackageName, childPkg, listMsgName) + p, _ = stripPackagePrefix(fmt.Sprintf("%s.%s", args.basePackageName, args.parentPackage), p) + listDef = &protoMsgListField{ + listType: p, + imports: []string{importPath(args.baseImportPath, args.basePackageName, childPkg)}, + } } else { // YANG lists are mapped to a repeated message structure as described // in the YANG to Protobuf transformation specification. @@ -678,14 +692,16 @@ func protoListDefinition(args protoDefinitionArgs) (string, *protoMsg, error) { parentPackage: args.parentPackage, }) if err != nil { - return "", nil, fmt.Errorf("proto: could not build mapping for list entry %s: %v", args.field.Path(), err) + return nil, nil, fmt.Errorf("proto: could not build mapping for list entry %s: %v", args.field.Path(), err) } // The type of this field is just the key message's name, since it // will be in the same package as the field's parent. - fieldType = listKeyMsg.Name + listDef = &protoMsgListField{ + listType: listKeyMsg.Name, + } } - return fieldType, listKeyMsg, nil + return listDef, listKeyMsg, nil } // protoDefinedLeaf defines a YANG leaf within a protobuf message. @@ -821,7 +837,7 @@ func genListKeyProto(listPackage string, listName string, args protoDefinitionAr } if listPackage != "" { - km.Imports = []string{filepath.Join(args.baseImportPath, args.basePackageName, strings.Replace(listPackage, ".", "/", -1))} + km.Imports = []string{importPath(args.baseImportPath, args.basePackageName, listPackage)} } definedFieldNames := map[string]bool{} @@ -874,6 +890,10 @@ func genListKeyProto(listPackage string, listName string, args protoDefinitionAr if isUnionType(target.Type) && scalarType.unionTypes != nil { unionEntry = target } + + if isIdentityrefLeaf(target) { + km.Imports = append(km.Imports, importPath(args.baseImportPath, args.basePackageName, args.enumPackageName)) + } case isSimpleEnumerationType(kf.Type): enumEntry = kf case isUnionType(kf.Type) && scalarType.unionTypes != nil: @@ -903,6 +923,9 @@ func genListKeyProto(listPackage string, listName string, args protoDefinitionAr for n, e := range u.enums { km.Enums[n] = e } + if u.hadGlobalEnums { + km.Imports = append(km.Imports, importPath(args.baseImportPath, args.basePackageName, args.enumPackageName)) + } default: fd.Type = scalarType.nativeType } @@ -1042,7 +1065,7 @@ func unionFieldToOneOf(fieldName string, e *yang.Entry, mtype *mappedType, annot // for the input package. func protoPackageToFilePath(pkg string) []string { pp := strings.Split(pkg, ".") - return append(pp[:len(pp)-1], fmt.Sprintf("%s.proto", pp[len(pp)-1])) + return append(pp, fmt.Sprintf("%s.proto", pp[len(pp)-1])) } // protoSchemaPathAnnotation takes a protobuf message and field, and returns the protobuf @@ -1081,3 +1104,10 @@ func stripPackagePrefix(pfx, path string) (string, bool) { return strings.Join(pathP[i+1:], "."), true } + +// importPath returns a string indicating the import path for a particular +// child package - considering the base import path, and base package name +// for the generated set of protobuf messages. +func importPath(baseImportPath, basePkgName, childPkg string) string { + return filepath.Join(append([]string{baseImportPath}, protoPackageToFilePath(fmt.Sprintf("%s.%s", basePkgName, childPkg))...)...) +} diff --git a/ygen/protogen_test.go b/ygen/protogen_test.go index a24698203..4ea5e2abc 100644 --- a/ygen/protogen_test.go +++ b/ygen/protogen_test.go @@ -154,7 +154,7 @@ func TestGenProto3Msg(t *testing.T) { "MessageName": { Name: "MessageName", YANGPath: "/root/message-name", - Imports: []string{"base/enums"}, + Imports: []string{"base/enums/enums.proto"}, Fields: []*protoMsgField{{ Tag: 410095931, Name: "field_one", @@ -250,7 +250,7 @@ func TestGenProto3Msg(t *testing.T) { Name: "container_child", Type: "a_message.ContainerChild", }}, - Imports: []string{"base/a_message"}, + Imports: []string{"base/a_message/a_message.proto"}, }, }, }, { @@ -312,7 +312,7 @@ func TestGenProto3Msg(t *testing.T) { Name: "container_child", Type: "root.a_message.ContainerChild", }}, - Imports: []string{"base/root/a_message"}, + Imports: []string{"base/root/a_message/a_message.proto"}, }, }, }, { @@ -398,7 +398,7 @@ func TestGenProto3Msg(t *testing.T) { Name: "list", Type: "a_message_with_a_list.List", }}, - Imports: []string{"base/a_message_with_a_list"}, + Imports: []string{"base/a_message_with_a_list/a_message_with_a_list.proto"}, }, }, }, { @@ -469,7 +469,7 @@ func TestGenProto3Msg(t *testing.T) { "MessageWithAnydata": { Name: "MessageWithAnydata", YANGPath: "/message-with-anydata", - Imports: []string{"google/protobuf/any"}, + Imports: []string{"google/protobuf/any.proto"}, Fields: []*protoMsgField{{ Tag: 453452743, Name: "any_data", @@ -1064,7 +1064,7 @@ func TestGenListKeyProto(t *testing.T) { Name: "list", Type: "pkg.list", }}, - Imports: []string{"base/path/base/pkg"}, + Imports: []string{"base/path/base/pkg/pkg.proto"}, }, }, { name: "list with union key - string and int", @@ -1124,7 +1124,7 @@ func TestGenListKeyProto(t *testing.T) { Name: "list", Type: "pkg.list", }}, - Imports: []string{"base/path/base/pkg"}, + Imports: []string{"base/path/base/pkg/pkg.proto"}, }, }, { name: "list with union key - two string", @@ -1175,7 +1175,7 @@ func TestGenListKeyProto(t *testing.T) { Name: "list", Type: "pkg.list", }}, - Imports: []string{"base/path/base/pkg"}, + Imports: []string{"base/path/base/pkg/pkg.proto"}, }, }} diff --git a/ygen/schemaparse_test.go b/ygen/schemaparse_test.go index 915ca893f..c56629ae8 100644 --- a/ygen/schemaparse_test.go +++ b/ygen/schemaparse_test.go @@ -16,7 +16,6 @@ package ygen import ( "encoding/json" - "fmt" "reflect" "strings" "testing" @@ -484,8 +483,6 @@ func TestSchemaRoundtrip(t *testing.T) { if !reflect.DeepEqual(got, tt.want) { // Use JSON serialisation for test debugging output. - fmt.Printf("%v\n", tt.want["Container"].Parent) - fmt.Printf("%v\n", got["Container"].Parent) gotj, _ := json.MarshalIndent(got, "", strings.Repeat(" ", 4)) wantj, _ := json.MarshalIndent(tt.want, "", strings.Repeat(" ", 4)) diff, _ := generateUnifiedDiff(string(gotj), string(wantj)) diff --git a/ygen/testdata/proto/proto-enums-addid.formatted-txt b/ygen/testdata/proto/proto-enums-addid.formatted-txt index b900d1162..c82bcd11e 100644 --- a/ygen/testdata/proto/proto-enums-addid.formatted-txt +++ b/ygen/testdata/proto/proto-enums-addid.formatted-txt @@ -10,7 +10,7 @@ package openconfig.proto_enums; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/enums.proto"; +import "openconfig/enums/enums.proto"; // A represents the /proto-enums/a YANG schema element. message A { diff --git a/ygen/testdata/proto/proto-enums.formatted-txt b/ygen/testdata/proto/proto-enums.formatted-txt index 173858920..21d6de61f 100644 --- a/ygen/testdata/proto/proto-enums.formatted-txt +++ b/ygen/testdata/proto/proto-enums.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_enums; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/enums.proto"; +import "openconfig/enums/enums.proto"; // A represents the /proto-enums/a YANG schema element. message A { diff --git a/ygen/testdata/proto/proto-test-a.compress.parent.formatted-txt b/ygen/testdata/proto/proto-test-a.compress.parent.formatted-txt index 9a0771549..bcb9c5e86 100644 --- a/ygen/testdata/proto/proto-test-a.compress.parent.formatted-txt +++ b/ygen/testdata/proto/proto-test-a.compress.parent.formatted-txt @@ -9,7 +9,7 @@ package openconfig; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/parent.proto"; +import "openconfig/parent/parent.proto"; // Parent represents the /proto-test-a/parent YANG schema element. message Parent { diff --git a/ygen/testdata/proto/proto-test-a.nocompress.formatted-txt b/ygen/testdata/proto/proto-test-a.nocompress.formatted-txt index 7c11c05ae..0db97eee5 100644 --- a/ygen/testdata/proto/proto-test-a.nocompress.formatted-txt +++ b/ygen/testdata/proto/proto-test-a.nocompress.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_a; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_a/parent.proto"; +import "openconfig/proto_test_a/parent/parent.proto"; // Parent represents the /proto-test-a/parent YANG schema element. message Parent { diff --git a/ygen/testdata/proto/proto-test-a.nocompress.parent.formatted-txt b/ygen/testdata/proto/proto-test-a.nocompress.parent.formatted-txt index e6e90e7f9..bc51055b5 100644 --- a/ygen/testdata/proto/proto-test-a.nocompress.parent.formatted-txt +++ b/ygen/testdata/proto/proto-test-a.nocompress.parent.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_a.parent; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_a/parent/child.proto"; +import "openconfig/proto_test_a/parent/child/child.proto"; // Child represents the /proto-test-a/parent/child YANG schema element. message Child { diff --git a/ygen/testdata/proto/proto-test-b.compress.formatted-txt b/ygen/testdata/proto/proto-test-b.compress.formatted-txt index 6fc4834b4..d474ced25 100644 --- a/ygen/testdata/proto/proto-test-b.compress.formatted-txt +++ b/ygen/testdata/proto/proto-test-b.compress.formatted-txt @@ -9,7 +9,7 @@ package openconfig; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/device.proto"; +import "openconfig/device/device.proto"; // InterfaceKey represents the /proto-test-b/device/interfaces/interface YANG schema element. message InterfaceKey { diff --git a/ygen/testdata/proto/proto-test-b.compress.interface.formatted-txt b/ygen/testdata/proto/proto-test-b.compress.interface.formatted-txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/ygen/testdata/proto/proto-test-c.device.formatted-txt b/ygen/testdata/proto/proto-test-c.device.formatted-txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/ygen/testdata/proto/proto-test-c.proto-test-c.elists.formatted-txt b/ygen/testdata/proto/proto-test-c.proto-test-c.elists.formatted-txt index b31465fd5..952e8979a 100644 --- a/ygen/testdata/proto/proto-test-c.proto-test-c.elists.formatted-txt +++ b/ygen/testdata/proto/proto-test-c.proto-test-c.elists.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_c.elists; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_c/elists/elist.proto"; +import "openconfig/proto_test_c/elists/elist/elist.proto"; // Elist represents the /proto-test-c/elists/elist YANG schema element. message Elist { diff --git a/ygen/testdata/proto/proto-test-c.proto-test-c.formatted-txt b/ygen/testdata/proto/proto-test-c.proto-test-c.formatted-txt index 486b2dfe3..bde776f71 100644 --- a/ygen/testdata/proto/proto-test-c.proto-test-c.formatted-txt +++ b/ygen/testdata/proto/proto-test-c.proto-test-c.formatted-txt @@ -9,8 +9,8 @@ package openconfig.proto_test_c; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_c/elists.proto"; -import "openconfig/proto_test_c/entity.proto"; +import "openconfig/proto_test_c/elists/elists.proto"; +import "openconfig/proto_test_c/entity/entity.proto"; // ElistKey represents the /proto-test-c/elists/elist YANG schema element. message ElistKey { diff --git a/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.formatted-txt b/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.formatted-txt index 99f0d54e5..c652ba04a 100644 --- a/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.formatted-txt +++ b/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_d; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_d/test.proto"; +import "openconfig/proto_test_d/test/test.proto"; // Test represents the /proto-test-d/test YANG schema element. message Test { diff --git a/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.test.formatted-txt b/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.test.formatted-txt index 762fdeb85..6b07b1e22 100644 --- a/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.test.formatted-txt +++ b/ygen/testdata/proto/proto-test-d.uncompressed.proto-test-d.test.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_d.test; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/enums.proto"; +import "openconfig/enums/enums.proto"; // Config represents the /proto-test-d/test/config YANG schema element. message Config { diff --git a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.animals.formatted-txt b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.animals.formatted-txt index 62f71b09d..f667168fd 100644 --- a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.animals.formatted-txt +++ b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.animals.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_e.animals; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_e/animals/animal.proto"; +import "openconfig/proto_test_e/animals/animal/animal.proto"; // Animal represents the /proto-test-e/animals/animal YANG schema element. message Animal { diff --git a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.foos.formatted-txt b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.foos.formatted-txt index 2528b36e3..fff1db779 100644 --- a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.foos.formatted-txt +++ b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.foos.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_e.foos; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_e/foos/foo.proto"; +import "openconfig/proto_test_e/foos/foo/foo.proto"; // Foo represents the /proto-test-e/foos/foo YANG schema element. message Foo { diff --git a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.formatted-txt b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.formatted-txt index 3243e8457..558b9fa0d 100644 --- a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.formatted-txt +++ b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.formatted-txt @@ -9,10 +9,10 @@ package openconfig.proto_test_e; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_e/animals.proto"; -import "openconfig/proto_test_e/bars.proto"; -import "openconfig/proto_test_e/foos.proto"; -import "openconfig/proto_test_e/test.proto"; +import "openconfig/proto_test_e/animals/animals.proto"; +import "openconfig/proto_test_e/bars/bars.proto"; +import "openconfig/proto_test_e/foos/foos.proto"; +import "openconfig/proto_test_e/test/test.proto"; // AnimalKey represents the /proto-test-e/animals/animal YANG schema element. message AnimalKey { diff --git a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.test.formatted-txt b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.test.formatted-txt index 16258f411..d18bfc787 100644 --- a/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.test.formatted-txt +++ b/ygen/testdata/proto/proto-test-e.uncompressed.proto-test-e.test.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_e.test; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/enums.proto"; +import "openconfig/enums/enums.proto"; // Config represents the /proto-test-e/test/config YANG schema element. message Config { diff --git a/ygen/testdata/proto/proto-union-list-key.compressed.openconfig.formatted-txt b/ygen/testdata/proto/proto-union-list-key.compressed.openconfig.formatted-txt index 49d8eead6..718cbf9a0 100644 --- a/ygen/testdata/proto/proto-union-list-key.compressed.openconfig.formatted-txt +++ b/ygen/testdata/proto/proto-union-list-key.compressed.openconfig.formatted-txt @@ -9,7 +9,7 @@ package openconfig; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/routing_policy.proto"; +import "openconfig/routing_policy/routing_policy.proto"; // Device represents the /device YANG schema element. message Device { diff --git a/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.formatted-txt b/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.formatted-txt index dd5601cad..da0b31824 100644 --- a/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.formatted-txt +++ b/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_union_list_key; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_union_list_key/routing_policy.proto"; +import "openconfig/proto_union_list_key/routing_policy/routing_policy.proto"; // RoutingPolicy represents the /proto-union-list-key/routing-policy YANG schema element. message RoutingPolicy { diff --git a/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.formatted-txt b/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.formatted-txt index 7871d591a..06af148cc 100644 --- a/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.formatted-txt +++ b/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.formatted-txt @@ -9,8 +9,8 @@ package openconfig.proto_union_list_key.routing_policy; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_union_list_key/routing_policy/policies.proto"; -import "openconfig/proto_union_list_key/routing_policy/sets.proto"; +import "openconfig/proto_union_list_key/routing_policy/policies/policies.proto"; +import "openconfig/proto_union_list_key/routing_policy/sets/sets.proto"; // PolicyKey represents the /proto-union-list-key/routing-policy/policies/policy YANG schema element. message PolicyKey { diff --git a/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.policies.formatted-txt b/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.policies.formatted-txt index cd61d375a..370ac5b6a 100644 --- a/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.policies.formatted-txt +++ b/ygen/testdata/proto/proto-union-list-key.uncompressed.openconfig.proto_union_list_key.routing_policy.policies.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_union_list_key.routing_policy.policies; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_union_list_key/routing_policy/policies/policy.proto"; +import "openconfig/proto_union_list_key/routing_policy/policies/policy/policy.proto"; // Policy represents the /proto-union-list-key/routing-policy/policies/policy YANG schema element. message Policy { diff --git a/ygen/testdata/proto/proto-union-list_key.uncompressed.openconfig.formatted-txt b/ygen/testdata/proto/proto-union-list_key.uncompressed.openconfig.formatted-txt index 682e0ef7a..bf6cfbab1 100644 --- a/ygen/testdata/proto/proto-union-list_key.uncompressed.openconfig.formatted-txt +++ b/ygen/testdata/proto/proto-union-list_key.uncompressed.openconfig.formatted-txt @@ -9,7 +9,7 @@ package openconfig; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_union_list_key.proto"; +import "openconfig/proto_union_list_key/proto_union_list_key.proto"; // Device represents the /device YANG schema element. message Device { diff --git a/ygen/testdata/proto/proto_anydata_test.formatted-txt b/ygen/testdata/proto/proto_anydata_test.formatted-txt index d7857854f..ffeb06326 100644 --- a/ygen/testdata/proto/proto_anydata_test.formatted-txt +++ b/ygen/testdata/proto/proto_anydata_test.formatted-txt @@ -10,7 +10,7 @@ package openconfig.proto_anydata_test; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; import "google/protobuf/any.proto"; -import "openconfig/proto_anydata_test/e.proto"; +import "openconfig/proto_anydata_test/e/e.proto"; // A represents the /proto-anydata-test/a YANG schema element. message A { diff --git a/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.a.formatted-txt b/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.a.formatted-txt index 55e24b477..d2306e03b 100644 --- a/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.a.formatted-txt +++ b/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.a.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_f.a; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_f/a/c.proto"; +import "openconfig/proto_test_f/a/c/c.proto"; // EKey represents the /proto-test-f/a/c/e YANG schema element. message EKey { diff --git a/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.formatted-txt b/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.formatted-txt index 10f24940e..85a525349 100644 --- a/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.formatted-txt +++ b/ygen/testdata/proto/proto_test_f.uncompressed.proto_test_f.formatted-txt @@ -9,7 +9,7 @@ package openconfig.proto_test_f; import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/proto_test_f/a.proto"; +import "openconfig/proto_test_f/a/a.proto"; // A represents the /proto-test-f/a YANG schema element. message A {