diff --git a/pyproject.toml b/pyproject.toml index b2e4f88be..fe3991e3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,8 @@ classifiers = [ [tool.poetry.dependencies] python = "~3.6 || ~3.7 || ^3.8" # Compatible python versions must be declared here pyang = "^2.3.2" -pyang-jsontree-plugin = "^0.1" +pyangbind="^0.8.1" +pygments-yang-lexer = "^0.2" # Optional dependencies (development) pudb = "^2019.2" diff --git a/yang/exabgp.yang b/yang/exabgp.yang new file mode 100644 index 000000000..ca9baae35 --- /dev/null +++ b/yang/exabgp.yang @@ -0,0 +1,452 @@ +module exabgp { + namespace "https://github.com/exa-networks/exabgp"; + prefix exabgp; + + import ietf-inet-types { + prefix ietf-inet-types; + } + + import openconfig-bgp-types { + prefix openconfig-bgp-types; + } + + organization + "Exa Networks"; + contact + "Thomas Mangin "; + description + "This yang module defines ExaBGP version 5 configuration"; + + revision 2020-08-15 { + description + "Initial revision."; + } + + typedef router-name { + description + "The IP address or DNS name of a router"; + type union { + type ietf-inet-types:ip-address; + type ietf-inet-types:domain-name; + } + } + + grouping nlri-v4 { + leaf prefix { + type ietf-inet-types:ipv4-address; + } + leaf prefix-length { + description + "The length of the subnet prefix"; + type uint8 { + range "0..32"; + } + } + } + + grouping nlri-v6 { + leaf prefix { + type ietf-inet-types:ipv6-address; + } + leaf prefix-length { + description + "The length of the subnet prefix"; + type uint8 { + range "0..128"; + } + } + } + + grouping nlri-path { + leaf path-information { + description + ""; + type ietf-inet-types:ip-address; + } + } + + grouping nlri-label { + leaf-list label { + description + ""; + type uint32 { + // 20 bits + range "0..1048575"; + } + } + } + + grouping nlri-rd { + leaf route-distinguisher { + description + ""; + type string { + // TODO validation + } + } + } + + grouping attributes-bgp { + leaf attribute { + description + ""; + type string; + } + leaf next-hop { + description + ""; + type ietf-inet-types:ip-address; + } + leaf origin { + description + ""; + type enumeration { + enum igp; + enum egp; + enum incomplete; + } + default incomplete; + } + leaf med { + description + ""; + type uint32; + default 0; + } + leaf local-preference { + description + ""; + type uint32; + default 100; + } + leaf-list community { + description + ""; + type openconfig-bgp-types:bgp-std-community-type; + } + leaf-list large-commity { + description + ""; + type string; + // constraint TODO + } + leaf-list extended-community { + description + ""; + type string; + // constraint TODO + } + leaf-list as-path { + description + ""; + type ietf-inet-types:as-number; + } + leaf-list aggregator { + description + ""; + type string; + // constraint TODO + } + leaf atomic-aggregate { + description + ""; + type boolean; + default "false"; + } + leaf originator-id { + description + ""; + type ietf-inet-types:ip-address; + } + leaf-list cluster-list { + description + ""; + type ietf-inet-types:ip-address; + } + leaf-list name { + description + ""; + type string; + } + leaf-list aigp { + description + ""; + type uint8; + } + } + + grouping attributes-v4 { + uses attributes-bgp { + refine split { + default 32; + } + } + leaf-list split { + description + ""; + type uint8 { + range "0..32"; + } + } + } + + grouping ipv4-unicast { + uses attributes-v4; + uses nlri-path; + uses nlri-v4; + } + + grouping ipv4-nlri-mpls { + uses attributes-v4; + uses nlri-label; + uses nlri-path; + uses nlri-v4; + } + + grouping ipv4-mpls-vpn { + uses attributes-v4; + uses nlri-rd; + uses nlri-label; + uses nlri-v4; + } + + grouping attributes-v6 { + uses attributes-bgp { + refine split { + default 32; + } + } + leaf-list split { + description + ""; + type uint8 { + range "0..128"; + } + } + } + + grouping ipv6-unicast { + uses attributes-v6; + uses nlri-path; + uses nlri-v6; + } + + grouping ipv6-nlri-mpls { + uses attributes-v6; + uses nlri-label; + uses nlri-path; + uses nlri-v6; + } + + grouping ipv6-mpls-vpn { + uses attributes-v6; + uses nlri-rd; + uses nlri-label; + uses nlri-v6; + } + + list process { + key "name"; + leaf name { + description + "The name of this process, so that it can be referenced"; + // need better validation + type string; + } + leaf run { + description + "The program to execute which will receive and send API messages"; + // need better validation + type string; + mandatory true; + } + leaf encoding { + description + "The codec to use when sending data to the process"; + type enumeration { + enum json; + enum text; + } + default json; + } + leaf respawn { + description + "Should the program be restarted should it exit"; + type boolean; + default "true"; + } + } + list neighbor { + // TODO + // 'host-name': hostname, + // 'domain-name': domainname, + key "neighbor"; + leaf neighbor { + description + "The IP address of the router"; + type router-name; + } + leaf description { + description + "A description for this router"; + type string; + } + leaf router-id { + description + "A unique 32 bit number for this router with the Autonomous system + expressed as an IPv4 address"; + type ietf-inet-types:ipv4-address; + } + leaf hold-time { + // describe BGP Hold time + description + ""; + type uint16 { + range "3..max"; + } + default 180; + } + leaf rate-limit { + description + "The maximum number of message handling per second + unset or set to zero to remove any limit"; + type uint32; + default 0; + } + leaf local-address { + description + ""; + type ietf-inet-types:ip-address; + mandatory true; + } + leaf peer-address { + description + ""; + type ietf-inet-types:ip-address; + mandatory true; + } + leaf local-as { + description + ""; + type ietf-inet-types:as-number; + mandatory true; + } + leaf peer-as { + description + ""; + type ietf-inet-types:as-number; + mandatory true; + } + leaf passive { + description + ""; + type boolean; + default "false"; + } + leaf listen { + description + ""; + type ietf-inet-types:port-number { + range "1..max"; + } + } + leaf connect { + description + ""; + type ietf-inet-types:port-number { + range "1..max"; + } + } + leaf outgoing-ttl { + description + ""; + // check if ttl 0 make sense + type uint8; + } + leaf incoming-ttl { + description + ""; + // check if ttl 0 make sense + type uint8; + } + leaf md5-password { + description + ""; + // check if ttl 0 make sense + type string; + } + leaf md5-base64 { + // unset is auto + description + ""; + type boolean; + } + leaf md5-ip { + // unset is auto + description + ""; + type ietf-inet-types:ipv4-address; + } + leaf group-updates { + description + ""; + type boolean; + default true; + } + leaf auto-flush { + description + ""; + type boolean; + default true; + } + leaf adj-rib-out { + description + ""; + type boolean; + default true; + } + leaf adj-rib-in { + description + ""; + type boolean; + default true; + } + leaf manual-eor { + description + ""; + type boolean; + default true; + } + } + container annnounce { + container ipv4 { + list unicast { + key "prefix prefix-length"; + uses ipv4-unicast; + } + list nlri-mpls { + key "prefix prefix-length"; + uses ipv4-nlri-mpls; + } + list mpls-vpn { + key "prefix prefix-length"; + uses ipv4-mpls-vpn; + } + } + container ipv6 { + list unicast { + key "prefix prefix-length"; + uses ipv6-unicast; + } + list nlri-mpls { + key "prefix prefix-length"; + uses ipv4-nlri-mpls; + } + list mpls-vpn { + key "prefix prefix-length"; + uses ipv6-mpls-vpn; + } + } + // missing flowspec and other families + } +} diff --git a/yang/generate b/yang/generate new file mode 100755 index 000000000..16978a4a2 --- /dev/null +++ b/yang/generate @@ -0,0 +1,482 @@ +#!/usr/bin/env python3 + +import re +import os +import sys +import json +import shutil +import pprint +import urllib.request +from glob import glob + +from pygments.token import Token +from yanglexer import yanglexer + +from yangson.datamodel import DataModel + + +def write(string): + if not string.startswith('\n'): + fill = ' ' * shutil.get_terminal_size().columns + sys.stdout.write(f'\r{fill}\r') + sys.stdout.write(f'{string}') + sys.stdout.flush() + + +def clean_models(folder): + print(f'cleaning {folder}') + for file in glob(f'{folder}/*.yang'): + print(f'cleanup: {file}') + os.remove(file) + print('done.\n') + + +def verify_yang(name, save): + # simple but should be enough + write(f'šŸ” checking {name} for correct yaml') + if not open(save).readline().startswith('module'): + write(f'šŸ„µ not-yang {name} does not contain a yang module') + return False + return True + + +def fetch_models(folder): + print('downloading models') + + namespaces = { + 'ietf': 'https://raw.githubusercontent.com/YangModels/yang/master/standard/ietf/RFC', + } + + data = json.loads(open('yang-library-data.json').read()) + for module in data['ietf-yang-library:modules-state']['module']: + name = module['name'] + revision = module['revision'] + yang = f'{name}@{revision}.yang' + save = f'{folder}/{name}.yang' + + if 'schema' in module: + url = module['schema'] + + elif 'namespace' in module: + namespace = module['namespace'].split(':') + site = namespaces.get(namespace[1],'') + if not site: + raise RuntimeError('unimplemented namespace case') + + url = f"{site}/{yang}" + else: + raise RuntimeError('unimplemented yang-library case') + + if os.path.exists(save): + write(f'šŸ‘Œ skipping {name} (already downloaded)') + if verify_yang(name, save): + write('\n') + continue + + write(f'šŸ‘ļø retrieve {name}@{revision} ({url})') + + try: + urllib.request.urlretrieve(url, save) + # indirect = urllib.request.urlopen(schema).read() + except urllib.error.HTTPError as exc: + write(f'\nšŸ„ŗ failure attempting to retrieve {url}\n{exc}') + return + + write(f'šŸ‘ retrieve {name}@{revision}') + if not verify_yang(name, save): + sys.exit(1) + write('\n') + + print('done.\n') + + +def check_models(): + try: + dm = DataModel.from_file( + "yang-library-data.json", [ + "models", + ]) + except Exception as exc: + sys.exit(str(exc)) + + +def convert_list(inside, elements): + for element in elements: + what = element.pop('type') + name = element.pop('name') + more = element.pop('children', []) + desc = element.pop('description', '') + + new = inside.setdefault(name, {}) + new[kw['description']] = desc + + if what == 'list': + return convert_list(new, more) + if what == 'container': + breakpoint() + pass + + if element: + raise RuntimeError('not consumed all the data') + + return inside + + +def convert_children(inside, tree): + for element in tree.get('children', []): + what = element.pop('type') + name = element.pop('name') + more = element.pop('children', []) + + new = inside.setdefault(name, {}) + new[kw['type']] = what + + if element: + raise RuntimeError('not consumed all the data') + + if what == 'list': + return convert_list(new, more) + if what == 'container': + breakpoint() + pass + + breakpoint() + pass + + return inside + + +def convert(tree): + inside = {} + + children = tree.pop('children', []) + for ignore in ('type', 'name', 'organization', 'contact', 'description'): + tree.pop(ignore) + + if tree: + raise RuntimeError('not consumed all the data') + + return convert_list(inside, children) + + +yang_types = ( + 'binary', + 'bits', + 'boolean', + 'decimal64', + 'empty', + 'enumeration', + 'identityref', + 'instance-identifier', + 'int8', + 'int16', + 'int32', + 'int64', + 'leafref', + 'string', + 'uint8', + 'uint16', + 'uint32', + 'uint64', + 'union', +) + + +yang_words = ( + 'namespace', + 'prefix', + 'description', + 'import', + 'organization', + 'contact', + 'description', + 'revision', + 'typedef', + 'type', + 'enumeration', + 'range', + 'grouping', + 'leaf', + 'leaf-list', + 'enum', + 'default', + 'key', + 'mandatory', + 'refine', + 'uses', + 'list', + 'container', + 'union', +) + + +kw = dict((w,f'[{w}]') for w in yang_words) + +replace = re.compile('\n\t') + +def formated(string): + s = string.strip() + if s and s[0] == s[-1]: + if s[0] in ('"', "'"): + s = s[1:-1] + s = re.sub(r'\n\t*\s*', ' ', s) + return s + + +Text = Token.Text +Single = Token.Comment.Singleline + + +class Lexer(object): + def __init__(self, yang, models): + self.name = yang.split('/')[-1].split('.')[0] + self.models = models + self.tree = { + self.name: {} + } + self.root = self.tree[self.name] + self.tokens = self.tokenise(yang) + + def tokenise(self, name): + lexer = yanglexer.YangLexer() + content = open(name).read() + tokens = lexer.get_tokens(content) + return [(t, n) for (t, n) in tokens if t not in (Text, Single)] + + def unexpected(self, string): + pprint.pprint(f'unexpected data {string}') + for t in self.tokens[:15]: + print(t) + breakpoint() + pass + + def head(self, what, expected=None): + token, string = self.tokens[0] + if not str(token).startswith(str(what)): + self.unexpected(string) + if expected is not None and string.strip() != expected: + self.unexpected(string) + self.tokens.pop(0) + return string + + def tail(self, what, expected=None): + token, string = self.tokens[-1] + if token != what: + self.unexpected(token, string) + if expected is not None and string != expected: + self.unexpected(token, string) + self.tokens.pop() + return string + + def namespace(self, result): + self.head(Token.Keyword.Namespace, 'module') + self.head(Token.Literal.String, 'exabgp') + self.head(Token.Punctuation, '{') + self.tail(Token.Punctuation, '}') + + def peek(self, position, ponctuation=None): + token, string = self.tokens[position] + # the self includes a last ' ' + if ponctuation and ponctuation != token: + self.unexpected(string) + return token, string.rstrip() + + def skip_keyword_block(self, name): + count = 0 + while True: + t, v = self.tokens.pop(0) + if t != Token.Punctuation: + continue + if v.strip() == '{': + count += 1 + if v.strip() == '}': + count -= 1 + if not count: + break + + def imports(self, module, prefix): + fname = os.path.join(self.models, module) + '.yang' + breakpoint() + if not os.path.exists(fname): + breakpoint() + # missing dependency, should not happen + pass + tokens = self.tokens + root = self.root + + self.tree[prefix] = {} + self.root = self.tree[prefix] + self.tokens = self.tokenise(fname) + self.parse() + + self.tokens = tokens + self.root = root + + def parse(self, tree=None): + if tree is None: + tree = self.root + self._parse([], tree) + return self.root + + def _parse(self, inside, tree): + while self.tokens: + token, string = self.peek(0) + + if token == Token.Punctuation and string == '}': + return + + if token == Token.Keyword.Namespace: + self.namespace(tree) + continue + + if token != Token.Keyword or string not in yang_words: + self.unknown() + continue + + self.head(Token.Keyword, string) + name = formated(self.head(Token.Literal.String)) + + if string in ('namespace', 'organization', 'contact', 'prefix'): + self.head(Token.Punctuation, ';') + continue + + if string == 'revision': + self.skip_keyword_block(Token.Punctuation) + continue + + if string == 'range': + self.head(Token.Punctuation, ';') + tree[kw[string]] = name + continue + + if string == 'import': + token, string = self.peek(0, Token.Punctuation) + if string == ';': + self.head(Token.Punctuation, ';') + # self.imports(name, name) + if string == '{': + self.head(Token.Punctuation, '{') + self.head(Token.Keyword, 'prefix') + prefix = formated(self.head(Token.Literal.String)) + self.head(Token.Punctuation, ';') + self.head(Token.Punctuation, '}') + # self.imports(name, prefix) + continue + + if string in ('description', 'default', 'mandatory'): + self.head(Token.Punctuation, ';') + tree[kw[string]] = name + continue + + if string == 'key': + self.head(Token.Punctuation, ';') + tree[kw[string]] = name.split() + continue + + if string == 'typedef': + self.head(Token.Punctuation, '{') + sub = tree.setdefault(kw[string], {}).setdefault(name, {}) + self._parse(inside + [name], sub) + self.head(Token.Punctuation, '}') + continue + + if string == 'enum': + self.head(Token.Punctuation, ';') + tree.setdefault(kw[string], []).append(name) + continue + + if string == 'type': + reference = self.root.get(kw['typedef'], {}).get(name, {}).get(kw[string], None) + if reference: + tree.setdefault(kw[string], reference) + self.head(Token.Punctuation, ';') + continue + + if name in ('union', 'enumeration'): + self.head(Token.Punctuation, '{') + sub = tree.setdefault(kw[string], {}).setdefault(name, {}) + self._parse(inside + [name], sub) + self.head(Token.Punctuation, '}') + continue + + if name in yang_types or ':' in name: + option = self.head(Token.Punctuation) + if option == ';': + tree.setdefault(kw[string], []).append(name) + continue + + if option == '{': + sub = tree.setdefault(kw[string], {}).setdefault(name, {}) + self._parse(inside + [name], sub) + self.head(Token.Punctuation, '}') + continue + + if string == 'uses': + tree.update(self.root['grouping'][name]) + option = self.head(Token.Punctuation) + if option == ';': + continue + if option == '{': + sub = tree.setdefault(name, {}) + self._parse(inside + [name], sub) + self.head(Token.Punctuation, '}') + continue + + if string == 'grouping': + self.head(Token.Punctuation, '{') + sub = self.root.setdefault('grouping', {}).setdefault(name, {}) + self._parse(inside + [name], sub) + self.head(Token.Punctuation, '}') + continue + + if string in ('container', 'list', 'refine', 'leaf', 'leaf-list'): + self.head(Token.Punctuation, '{') + sub = tree.setdefault(name, {}) + self._parse(inside + [name], sub) + self.head(Token.Punctuation, '}') + continue + + self.unknown() + + def unknown(self): + # catch unknown keyword so we can implement them + pprint.pprint(self.root) + pprint.pprint() + pprint.pprint(string) + pprint.pprint(name) + pprint.pprint() + for t in self.tokens[:15]: + pprint.pprint(t) + breakpoint() + # good luck! + pass + + +def make_tree(yang, models, python): + root = Lexer(yang, models).parse() + print(pprint.pformat(root)) + print() + + print(f'generating {python}') + with open(python, 'w') as w: + w.write('# yang model converted to dict\n') + w.write('\n') + w.write('model = ') + w.write(str(root)) + w.write('\n') + + +def main(): + folder = os.path.dirname(__file__) + os.chdir(os.path.abspath(folder)) + + if not os.path.exists('models'): + os.mkdir('models') + + fetch_models('models') + check_models() + make_tree('exabgp.yang', 'models', 'model.py') + + +if __name__ == "__main__": + main() diff --git a/yang/models/exabgp.yang b/yang/models/exabgp.yang new file mode 100644 index 000000000..ca9baae35 --- /dev/null +++ b/yang/models/exabgp.yang @@ -0,0 +1,452 @@ +module exabgp { + namespace "https://github.com/exa-networks/exabgp"; + prefix exabgp; + + import ietf-inet-types { + prefix ietf-inet-types; + } + + import openconfig-bgp-types { + prefix openconfig-bgp-types; + } + + organization + "Exa Networks"; + contact + "Thomas Mangin "; + description + "This yang module defines ExaBGP version 5 configuration"; + + revision 2020-08-15 { + description + "Initial revision."; + } + + typedef router-name { + description + "The IP address or DNS name of a router"; + type union { + type ietf-inet-types:ip-address; + type ietf-inet-types:domain-name; + } + } + + grouping nlri-v4 { + leaf prefix { + type ietf-inet-types:ipv4-address; + } + leaf prefix-length { + description + "The length of the subnet prefix"; + type uint8 { + range "0..32"; + } + } + } + + grouping nlri-v6 { + leaf prefix { + type ietf-inet-types:ipv6-address; + } + leaf prefix-length { + description + "The length of the subnet prefix"; + type uint8 { + range "0..128"; + } + } + } + + grouping nlri-path { + leaf path-information { + description + ""; + type ietf-inet-types:ip-address; + } + } + + grouping nlri-label { + leaf-list label { + description + ""; + type uint32 { + // 20 bits + range "0..1048575"; + } + } + } + + grouping nlri-rd { + leaf route-distinguisher { + description + ""; + type string { + // TODO validation + } + } + } + + grouping attributes-bgp { + leaf attribute { + description + ""; + type string; + } + leaf next-hop { + description + ""; + type ietf-inet-types:ip-address; + } + leaf origin { + description + ""; + type enumeration { + enum igp; + enum egp; + enum incomplete; + } + default incomplete; + } + leaf med { + description + ""; + type uint32; + default 0; + } + leaf local-preference { + description + ""; + type uint32; + default 100; + } + leaf-list community { + description + ""; + type openconfig-bgp-types:bgp-std-community-type; + } + leaf-list large-commity { + description + ""; + type string; + // constraint TODO + } + leaf-list extended-community { + description + ""; + type string; + // constraint TODO + } + leaf-list as-path { + description + ""; + type ietf-inet-types:as-number; + } + leaf-list aggregator { + description + ""; + type string; + // constraint TODO + } + leaf atomic-aggregate { + description + ""; + type boolean; + default "false"; + } + leaf originator-id { + description + ""; + type ietf-inet-types:ip-address; + } + leaf-list cluster-list { + description + ""; + type ietf-inet-types:ip-address; + } + leaf-list name { + description + ""; + type string; + } + leaf-list aigp { + description + ""; + type uint8; + } + } + + grouping attributes-v4 { + uses attributes-bgp { + refine split { + default 32; + } + } + leaf-list split { + description + ""; + type uint8 { + range "0..32"; + } + } + } + + grouping ipv4-unicast { + uses attributes-v4; + uses nlri-path; + uses nlri-v4; + } + + grouping ipv4-nlri-mpls { + uses attributes-v4; + uses nlri-label; + uses nlri-path; + uses nlri-v4; + } + + grouping ipv4-mpls-vpn { + uses attributes-v4; + uses nlri-rd; + uses nlri-label; + uses nlri-v4; + } + + grouping attributes-v6 { + uses attributes-bgp { + refine split { + default 32; + } + } + leaf-list split { + description + ""; + type uint8 { + range "0..128"; + } + } + } + + grouping ipv6-unicast { + uses attributes-v6; + uses nlri-path; + uses nlri-v6; + } + + grouping ipv6-nlri-mpls { + uses attributes-v6; + uses nlri-label; + uses nlri-path; + uses nlri-v6; + } + + grouping ipv6-mpls-vpn { + uses attributes-v6; + uses nlri-rd; + uses nlri-label; + uses nlri-v6; + } + + list process { + key "name"; + leaf name { + description + "The name of this process, so that it can be referenced"; + // need better validation + type string; + } + leaf run { + description + "The program to execute which will receive and send API messages"; + // need better validation + type string; + mandatory true; + } + leaf encoding { + description + "The codec to use when sending data to the process"; + type enumeration { + enum json; + enum text; + } + default json; + } + leaf respawn { + description + "Should the program be restarted should it exit"; + type boolean; + default "true"; + } + } + list neighbor { + // TODO + // 'host-name': hostname, + // 'domain-name': domainname, + key "neighbor"; + leaf neighbor { + description + "The IP address of the router"; + type router-name; + } + leaf description { + description + "A description for this router"; + type string; + } + leaf router-id { + description + "A unique 32 bit number for this router with the Autonomous system + expressed as an IPv4 address"; + type ietf-inet-types:ipv4-address; + } + leaf hold-time { + // describe BGP Hold time + description + ""; + type uint16 { + range "3..max"; + } + default 180; + } + leaf rate-limit { + description + "The maximum number of message handling per second + unset or set to zero to remove any limit"; + type uint32; + default 0; + } + leaf local-address { + description + ""; + type ietf-inet-types:ip-address; + mandatory true; + } + leaf peer-address { + description + ""; + type ietf-inet-types:ip-address; + mandatory true; + } + leaf local-as { + description + ""; + type ietf-inet-types:as-number; + mandatory true; + } + leaf peer-as { + description + ""; + type ietf-inet-types:as-number; + mandatory true; + } + leaf passive { + description + ""; + type boolean; + default "false"; + } + leaf listen { + description + ""; + type ietf-inet-types:port-number { + range "1..max"; + } + } + leaf connect { + description + ""; + type ietf-inet-types:port-number { + range "1..max"; + } + } + leaf outgoing-ttl { + description + ""; + // check if ttl 0 make sense + type uint8; + } + leaf incoming-ttl { + description + ""; + // check if ttl 0 make sense + type uint8; + } + leaf md5-password { + description + ""; + // check if ttl 0 make sense + type string; + } + leaf md5-base64 { + // unset is auto + description + ""; + type boolean; + } + leaf md5-ip { + // unset is auto + description + ""; + type ietf-inet-types:ipv4-address; + } + leaf group-updates { + description + ""; + type boolean; + default true; + } + leaf auto-flush { + description + ""; + type boolean; + default true; + } + leaf adj-rib-out { + description + ""; + type boolean; + default true; + } + leaf adj-rib-in { + description + ""; + type boolean; + default true; + } + leaf manual-eor { + description + ""; + type boolean; + default true; + } + } + container annnounce { + container ipv4 { + list unicast { + key "prefix prefix-length"; + uses ipv4-unicast; + } + list nlri-mpls { + key "prefix prefix-length"; + uses ipv4-nlri-mpls; + } + list mpls-vpn { + key "prefix prefix-length"; + uses ipv4-mpls-vpn; + } + } + container ipv6 { + list unicast { + key "prefix prefix-length"; + uses ipv6-unicast; + } + list nlri-mpls { + key "prefix prefix-length"; + uses ipv4-nlri-mpls; + } + list mpls-vpn { + key "prefix prefix-length"; + uses ipv6-mpls-vpn; + } + } + // missing flowspec and other families + } +} diff --git a/yang/models/ietf-inet-types.yang b/yang/models/ietf-inet-types.yang new file mode 100644 index 000000000..eacefb636 --- /dev/null +++ b/yang/models/ietf-inet-types.yang @@ -0,0 +1,458 @@ +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/yang/models/ietf-yang-library.yang b/yang/models/ietf-yang-library.yang new file mode 100644 index 000000000..e6221a60a --- /dev/null +++ b/yang/models/ietf-yang-library.yang @@ -0,0 +1,244 @@ +module ietf-yang-library { + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library"; + prefix "yanglib"; + + import ietf-yang-types { + prefix yang; + } + import ietf-inet-types { + prefix inet; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: Mehmet Ersue + + + WG Chair: Mahesh Jethanandani + + + Editor: Andy Bierman + + + Editor: Martin Bjorklund + + + Editor: Kent Watsen + "; + + description + "This module contains monitoring information about the YANG + modules and submodules that are used within a YANG-based + server. + + Copyright (c) 2016 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 7895; see + the RFC itself for full legal notices."; + + revision 2016-06-21 { + description + "Initial revision."; + reference + "RFC 7895: YANG Module Library."; + } + + /* + * Typedefs + */ + + typedef revision-identifier { + type string { + pattern '\d{4}-\d{2}-\d{2}'; + } + description + "Represents a specific date in YYYY-MM-DD format."; + } + + /* + * Groupings + */ + + grouping module-list { + description + "The module data structure is represented as a grouping + so it can be reused in configuration or another monitoring + data structure."; + + grouping common-leafs { + description + "Common parameters for YANG modules and submodules."; + + leaf name { + type yang:yang-identifier; + description + "The YANG module or submodule name."; + } + leaf revision { + type union { + type revision-identifier; + type string { length 0; } + } + description + "The YANG module or submodule revision date. + A zero-length string is used if no revision statement + is present in the YANG module or submodule."; + } + } + + grouping schema-leaf { + description + "Common schema leaf parameter for modules and submodules."; + + leaf schema { + type inet:uri; + description + "Contains a URL that represents the YANG schema + resource for this module or submodule. + + This leaf will only be present if there is a URL + available for retrieval of the schema for this entry."; + } + } + + list module { + key "name revision"; + description + "Each entry represents one revision of one module + currently supported by the server."; + + uses common-leafs; + uses schema-leaf; + + leaf namespace { + type inet:uri; + mandatory true; + description + "The XML namespace identifier for this module."; + } + leaf-list feature { + type yang:yang-identifier; + description + "List of YANG feature names from this module that are + supported by the server, regardless of whether they are + defined in the module or any included submodule."; + } + list deviation { + key "name revision"; + description + "List of YANG deviation module names and revisions + used by this server to modify the conformance of + the module associated with this entry. Note that + the same module can be used for deviations for + multiple modules, so the same entry MAY appear + within multiple 'module' entries. + + The deviation module MUST be present in the 'module' + list, with the same name and revision values. + The 'conformance-type' value will be 'implement' for + the deviation module."; + uses common-leafs; + } + leaf conformance-type { + type enumeration { + enum implement { + description + "Indicates that the server implements one or more + protocol-accessible objects defined in the YANG module + identified in this entry. This includes deviation + statements defined in the module. + + For YANG version 1.1 modules, there is at most one + module entry with conformance type 'implement' for a + particular module name, since YANG 1.1 requires that, + at most, one revision of a module is implemented. + + For YANG version 1 modules, there SHOULD NOT be more + than one module entry for a particular module name."; + } + enum import { + description + "Indicates that the server imports reusable definitions + from the specified revision of the module but does + not implement any protocol-accessible objects from + this revision. + + Multiple module entries for the same module name MAY + exist. This can occur if multiple modules import the + same module but specify different revision dates in + the import statements."; + } + } + mandatory true; + description + "Indicates the type of conformance the server is claiming + for the YANG module identified by this entry."; + } + list submodule { + key "name revision"; + description + "Each entry represents one submodule within the + parent module."; + uses common-leafs; + uses schema-leaf; + } + } + } + + /* + * Operational state data nodes + */ + + container modules-state { + config false; + description + "Contains YANG module monitoring information."; + + leaf module-set-id { + type string; + mandatory true; + description + "Contains a server-specific identifier representing + the current set of modules and submodules. The + server MUST change the value of this leaf if the + information represented by the 'module' list instances + has changed."; + } + + uses module-list; + } + + /* + * Notifications + */ + + notification yang-library-change { + description + "Generated when the set of modules and submodules supported + by the server has changed."; + leaf module-set-id { + type leafref { + path "/yanglib:modules-state/yanglib:module-set-id"; + } + mandatory true; + description + "Contains the module-set-id value representing the + set of modules and submodules supported at the server at + the time the notification is generated."; + } + } + +} diff --git a/yang/models/ietf-yang-types.yang b/yang/models/ietf-yang-types.yang new file mode 100644 index 000000000..ee58fa3ab --- /dev/null +++ b/yang/models/ietf-yang-types.yang @@ -0,0 +1,474 @@ +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/yang/models/openconfig-bgp-types.yang b/yang/models/openconfig-bgp-types.yang new file mode 100644 index 000000000..5e7164fc3 --- /dev/null +++ b/yang/models/openconfig-bgp-types.yang @@ -0,0 +1,671 @@ +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 "5.2.0"; + + revision "2020-06-17" { + description + "Add RFC5549 capability identity."; + reference "5.2.0"; + } + + revision "2020-03-24" { + description + "Add FlowSpec, BGP-LS and LSVR AFI-SAFI identities."; + reference "5.1.0"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "5.0.2"; + } + + revision "2018-08-20" { + description + "Correct description of AFI-SAFI enabled leaf."; + reference "5.0.1"; + } + + revision "2018-04-11" { + description + "Correct naming of BGP maximum prefix warning percentage leaf."; + reference "5.0.0"; + } + + revision "2018-03-20" { + description + "Added SR-TE policy SAFI"; + reference "4.1.0"; + } + + revision "2018-03-20" { + description + "Added color extended community"; + reference "4.0.2"; + } + + 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"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + 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 EXTENDED_NEXTHOP_ENCODING { + base BGP_CAPABILITY; + description + "BGP Extended Next Hop Encoding functionality"; + reference "RFC5549"; + } + + 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 SRTE_POLICY_IPV4 { + base AFI_SAFI_TYPE; + description + "Segment Routing Traffic Engineering (SRTE) Policy + for IPv4 (AFI,SAFI = 1,73)"; + } + + identity SRTE_POLICY_IPV6 { + base AFI_SAFI_TYPE; + description + "Segment Routing Traffic Engineering (SRTE) Policy + for IPv6 (AFI,SAFI = 2,73)"; + } + + identity IPV4_FLOWSPEC { + base AFI_SAFI_TYPE; + description + "IPv4 dissemination of flow specification rules + (AFI,SAFI = 1,133)"; + reference "RFC5575"; + } + + identity VPNV4_FLOWSPEC { + base AFI_SAFI_TYPE; + description + "IPv4 dissemination of flow specification rules + (AFI,SAFI = 1,134)"; + reference "RFC5575"; + } + + identity LINKSTATE { + base AFI_SAFI_TYPE; + description + "BGP-LS (AFI,SAFI = 16388,71)"; + reference "RFC7752"; + } + + identity LINKSTATE_VPN { + base AFI_SAFI_TYPE; + description + "BGP-LS-VPN (AFI,SAFI = 16388,72)"; + reference "RFC7752"; + } + + identity LINKSTATE_SPF { + base AFI_SAFI_TYPE; + description + "BGP-LS SPF (AFI,SAFI = 16388,TBD)"; + reference "draft-ietf-lsvr-bgp-spf"; + } + + + 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])$'; + } + type string { + // Extended Color Community + pattern '^color:' + + '[0-1]{2}:' + + '(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])$'; + } + } + 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 + - color::<4b value> per draft-ietf-idr-segment-routing-te-policy + section 3"; + reference + "RFC 4360 - BGP Extended Communities Attribute + RFC 5668 - 4-Octet AS Specific BGP Extended Community + draft-ietf-idr-segment-routing-te-policy"; + } + + 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/yang/models/openconfig-extensions.yang b/yang/models/openconfig-extensions.yang new file mode 100644 index 000000000..0ab7560eb --- /dev/null +++ b/yang/models/openconfig-extensions.yang @@ -0,0 +1,195 @@ +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 "2018-10-17" { + description + "Add extension for regular expression type."; + reference "0.4.0"; + } + + 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. + + Individual YANG modules are versioned independently -- the + semantic version is generally incremented only when there is a + change in the corresponding file. Submodules should always + have the same semantic version as their parent modules. + + 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."; + } + + extension regexp-posix { + description + "This extension indicates that the regular expressions included + within the YANG module specified are conformant with the POSIX + regular expression format rather than the W3C standard that is + specified by RFC6020 and RFC7950."; + } + + extension posix-pattern { + argument "pattern" { + yin-element false; + } + description + "Provides a POSIX ERE regular expression pattern statement as an + alternative to YANG regular expresssions based on XML Schema Datatypes. + It is used the same way as the standard YANG pattern statement defined in + RFC6020 and RFC7950, but takes an argument that is a POSIX ERE regular + expression string. + + If present, any posix-pattern statement should have a corresponding + pattern statement that provides equivalent behavior."; + reference + "POSIX Extended Regular Expressions (ERE) Specification: + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04"; + } + + extension telemetry-on-change { + description + "The telemetry-on-change annotation is specified in the context + of a particular subtree (container, or list) or leaf within the + YANG schema. Where specified, it indicates that the value stored + by the nodes within the context change their value only in response + to an event occurring. The event may be local to the target, for + example - a configuration change, or external - such as the failure + of a link. + + When a telemetry subscription allows the target to determine whether + to export the value of a leaf in a periodic or event-based fashion + (e.g., TARGET_DEFINED mode in gNMI), leaves marked as + telemetry-on-change should only be exported when they change, + i.e., event-based."; + } + + extension telemetry-atomic { + description + "The telemetry-atomic annotation is specified in the context of + a subtree (containre, or list), and indicates that all nodes + within the subtree are always updated together within the data + model. For example, all elements under the subtree may be updated + as a result of a new alarm being raised, or the arrival of a new + protocol message. + + Transport protocols may use the atomic specification to determine + optimisations for sending or storing the corresponding data."; + } + + extension operational { + description + "The operational annotation is specified in the context of a + grouping, leaf, or leaf-list within a YANG module. It indicates + that the nodes within the context are derived state on the device. + + OpenConfig data models divide nodes into the following three categories: + + - intended configuration - these are leaves within a container named + 'config', and are the writable configuration of a target. + - applied configuration - these are leaves within a container named + 'state' and are the currently running value of the intended configuration. + - derived state - these are the values within the 'state' container which + are not part of the applied configuration of the device. Typically, they + represent state values reflecting underlying operational counters, or + protocol statuses."; + } + + extension catalog-organization { + argument "org" { + yin-element false; + } + description + "This extension specifies the organization name that should be used within + the module catalogue on the device for the specified YANG module. It stores + a pithy string where the YANG organization statement may contain more + details."; + } + + extension origin { + argument "origin" { + yin-element false; + } + description + "This extension specifies the name of the origin that the YANG module + falls within. This allows multiple overlapping schema trees to be used + on a single network element without requiring module based prefixing + of paths."; + } +} diff --git a/yang/models/openconfig-inet-types.yang b/yang/models/openconfig-inet-types.yang new file mode 100644 index 000000000..904ffd899 --- /dev/null +++ b/yang/models/openconfig-inet-types.yang @@ -0,0 +1,349 @@ +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.3"; + + revision "2019-04-25" { + description + "Fix regex bug for ipv6-prefix type"; + reference "0.3.3"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.3.2"; + } + + 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"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // 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/yang/models/openconfig-types.yang b/yang/models/openconfig-types.yang new file mode 100644 index 000000000..89e32d515 --- /dev/null +++ b/yang/models/openconfig-types.yang @@ -0,0 +1,471 @@ +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.6.0"; + + revision "2019-04-16" { + description + "Clarify definition of timeticks64."; + reference "0.6.0"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.5.1"; + } + + revision "2018-05-05" { + description + "Add grouping of min-max-time and + included them to all stats with min/max/avg"; + reference "0.5.0"; + } + + revision "2018-01-16" { + description + "Add interval to min/max/avg stats; add percentage stat"; + reference "0.4.0"; + } + + 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"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + 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; + units "nanoseconds"; + description + "The timeticks64 represents the time, modulo 2^64 in + nanoseconds between two epochs. The leaf using this + type must define the epochs that tests are relative to."; + } + + 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."; + } + + typedef stat-interval { + type uint64; + units nanoseconds; + description + "A time interval over which a set of statistics is computed. + A common usage is to report the interval over which + avg/min/max stats are computed and reported."; + } + + grouping stat-interval-state { + description + "Reusable leaf definition for stats computation interval"; + + leaf interval { + type oc-types:stat-interval; + description + "If supported by the system, this reports the time interval + over which the min/max/average statistics are computed by + the system."; + } + } + + grouping min-max-time { + description + "Common grouping for recording the absolute time at which + the minimum and maximum values occurred in the statistics"; + + leaf min-time { + type oc-types:timeticks64; + description + "The absolute time at which the minimum value occurred. + The value is the timestamp in nanoseconds relative to + the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf max-time { + type oc-types:timeticks64; + description + "The absolute time at which the maximum value occurred. + The value is the timestamp in nanoseconds relative to + the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + } + } + + 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. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed is also reported."; + + leaf avg { + type decimal64 { + fraction-digits 1; + } + description + "The arithmetic mean value of the statistic over the + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 1; + } + description + "The minimum value of the statistic over the time + interval."; + } + + leaf max { + type decimal64 { + fraction-digits 1; + } + description + "The maximum value of the statitic over the time + interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + 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. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + 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 + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The minimum value of the statistic over the time interval."; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The maximum value of the statistic over the time + interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + 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. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + 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 + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The minimum value of the statistic over the time + interval."; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The maximum value of the statistic over the time interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + 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. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + 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 + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The minimum value of the statistic over the time + interval."; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The maximum value of the statistic over the time + interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + grouping avg-min-max-instant-stats-pct { + description + "Common grouping for percentage statistics. + Values include the instantaneous, average, + minimum, and maximum statistics. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + leaf instant { + type oc-types:percentage; + description + "The instantaneous percentage value."; + } + + leaf avg { + type oc-types:percentage; + description + "The arithmetic mean value of the percentage measure of the + statistic over the time interval."; + } + + leaf min { + type oc-types:percentage; + description + "The minimum value of the percentage measure of the + statistic over the time interval."; + } + + leaf max { + type oc-types:percentage; + description + "The maximum value of the percentage measure of the + statistic over the time interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + 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/yang/yang-library-data.json b/yang/yang-library-data.json new file mode 100644 index 000000000..0679215f8 --- /dev/null +++ b/yang/yang-library-data.json @@ -0,0 +1,59 @@ +{ + "ietf-yang-library:modules-state": { + "module-set-id": "exabgp00", + "module": [ + { + "name": "ietf-yang-library", + "revision": "2016-06-21", + "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library", + "conformance-type": "implement" + }, + { + "name": "ietf-yang-types", + "revision": "2013-07-15", + "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types", + "conformance-type": "import", + "schema": "https://raw.githubusercontent.com/YangModels/yang/master/standard/ietf/RFC/ietf-yang-types@2013-07-15.yang" + }, + { + "name": "openconfig-bgp-types", + "revision": "2020-06-17", + "namespace": "urn:ietf:params:xml:ns:yang:openconfig-bgp-types", + "conformance-type": "implement", + "schema": "https://raw.githubusercontent.com/openconfig/public/master/release/models/bgp/openconfig-bgp-types.yang" + }, + { + "required by": "openconfig-bgp-types", + "name": "openconfig-types", + "revision": "2019-04-16", + "namespace": "urn:ietf:params:xml:ns:yang:openconfig-types", + "conformance-type": "implement", + "schema": "https://raw.githubusercontent.com/openconfig/public/master/release/models/types/openconfig-types.yang" + }, + { + "required by": "openconfig-bgp-types", + "name": "openconfig-inet-types", + "revision": "2019-04-25", + "namespace": "urn:ietf:params:xml:ns:yang:openconfig-inet-types", + "conformance-type": "implement", + "schema": "https://raw.githubusercontent.com/openconfig/public/master/release/models/types/openconfig-inet-types.yang" + }, + { + "required by": "openconfig-bgp-types", + "name": "ietf-inet-types", + "revision": "2013-07-15", + "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types", + "conformance-type": "implement", + "schema": "https://raw.githubusercontent.com/YangModels/yang/master/standard/ietf/RFC/ietf-inet-types@2013-07-15.yang" + }, + { + "required by": "openconfig-*", + "name": "openconfig-extensions", + "revision": "2018-10-17", + "namespace": "urn:ietf:params:xml:ns:yang:openconfig-extensions", + "conformance-type": "import", + "schema": "https://raw.githubusercontent.com/openconfig/public/master/release/models/openconfig-extensions.yang" + } + ] + } +}