summaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-01-23 17:18:56 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-01-25 04:57:11 -0800
commitd94f5d2c03b8eb265cfa1af5dce43da7194538b8 (patch)
tree94872abec34c97a19c9abe457b10217d8c44964a /tools
parent3817b82f9d57ce02adb025f5acff6f06b54c6641 (diff)
config: add openconfig identity structs in bgp_configs.go
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'tools')
-rw-r--r--tools/pyang_plugins/bgpyang2golang.py151
-rw-r--r--tools/pyang_plugins/gobgp.yang69
2 files changed, 153 insertions, 67 deletions
diff --git a/tools/pyang_plugins/bgpyang2golang.py b/tools/pyang_plugins/bgpyang2golang.py
index 64d4d97c..45a25078 100644
--- a/tools/pyang_plugins/bgpyang2golang.py
+++ b/tools/pyang_plugins/bgpyang2golang.py
@@ -94,6 +94,7 @@ def emit_go(ctx):
for mod in ctx.module_deps:
if mod not in _module_excluded:
emit_typedef(ctx, mod)
+ emit_identity(ctx, mod)
for struct in ctx.golang_struct_def:
struct_name = struct.uniq_name
@@ -154,7 +155,7 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix):
# case identityref
if type_name == 'identityref':
- emit_type_name = 'string'
+ emit_type_name = convert_to_golang(type_obj.search_one('base').arg.split(':')[-1])
# case leafref
elif type_name == 'leafref':
@@ -163,6 +164,8 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix):
print >> o, ' //%s:%s\'s original type is %s' \
% (child_prefix, container_or_list_name, t.arg)
emit_type_name = translate_type(t.arg)
+ elif is_identityref(t):
+ emit_type_name = convert_to_golang(t.search_one('base').arg.split(':')[-1])
else:
emit_type_name = t.arg
@@ -203,6 +206,9 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix):
t = type_obj.i_type_spec.i_target_node.search_one('type')
emit_type_name = '[]'+t.arg
+ elif type_name == 'identityref':
+ emit_type_name = '[]'+convert_to_golang(type_obj.search_one('base').arg.split(':')[-1])
+
# case translation required
elif is_translation_required(type_obj):
print >> o, ' // original type is list of %s' % (type_obj.arg)
@@ -372,6 +378,15 @@ def visit_identity(ctx, module):
name = stmts.arg
stmts.golang_name = convert_to_golang(name)
child_map[name] = stmts
+
+ base = stmts.search_one('base')
+ if base:
+ elems = base.arg.split(':')
+ if len(elems) > 1:
+ ctx.golang_identity_map[elems[0]][elems[1]].substmts.append(stmts)
+ else:
+ child_map[base.arg].substmts.append(stmts)
+
ctx.golang_identity_map[prefix] = child_map
@@ -398,6 +413,68 @@ def lookup(basemap, default_prefix, key):
return key
+def emit_enum(prefix, name, stmt, substmts):
+ type_name_org = name
+ type_name = stmt.golang_name
+ o = StringIO.StringIO()
+
+ print >> o, '// typedef for identity %s:%s' % (prefix, type_name_org)
+ print >> o, 'type %s string' % (type_name)
+
+ const_prefix = convert_const_prefix(type_name_org)
+ print >> o, 'const ('
+ m = {}
+ for sub in substmts:
+ enum_name = '%s_%s' % (const_prefix, convert_const_prefix(sub.arg))
+ m[sub.arg.lower()] = enum_name
+ print >> o, ' %s %s = "%s"' % (enum_name, type_name, sub.arg.lower())
+ print >> o, ')\n'
+
+ print >> o, 'var %sToIntMap = map[%s]int {' % (type_name, type_name)
+ for i, sub in enumerate(substmts):
+ enum_name = '%s_%s' % (const_prefix, convert_const_prefix(sub.arg))
+ print >> o, ' %s: %d,' % (enum_name, i)
+ print >> o, '}\n'
+
+ print >> o, 'func (v %s) ToInt() int {' % (type_name)
+ print >> o, 'i, ok := %sToIntMap[v]' % (type_name)
+ print >> o, 'if !ok {'
+ print >> o, 'return -1'
+ print >> o, '}'
+ print >> o, 'return i'
+ print >> o, '}'
+
+ print >> o, 'var IntTo%sMap = map[int]%s {' % (type_name, type_name)
+ for i, sub in enumerate(substmts):
+ enum_name = '%s_%s' % (const_prefix, convert_const_prefix(sub.arg))
+ print >> o, ' %d: %s,' % (i, enum_name)
+ print >> o, '}\n'
+
+ print >> o, 'func (v %s) Validate() error {' % (type_name)
+ print >> o, 'if _, ok := %sToIntMap[v]; !ok {' % (type_name)
+ print >> o, 'return fmt.Errorf("invalid %s: %%s", v)' % (type_name)
+ print >> o, '}'
+ print >> o, 'return nil'
+ print >> o, '}\n'
+
+ if stmt.search_one('default'):
+ default = stmt.search_one('default')
+ print >> o, 'func (v %s) Default() %s {' % (type_name, type_name)
+ print >> o, 'return %s' % m[default.arg.lower()]
+ print >> o, '}\n'
+
+ print >> o, 'func (v %s) DefaultAsNeeded() %s {' % (type_name, type_name)
+ print >> o, ' if string(v) == "" {'
+ print >> o, ' return v.Default()'
+ print >> o, '}'
+ print >> o, ' return v'
+ print >> o, '}'
+
+
+
+ print o.getvalue()
+
+
def emit_typedef(ctx, module):
prefix = module.i_prefix
t_map = ctx.golang_typedef_map[prefix]
@@ -424,55 +501,7 @@ def emit_typedef(ctx, module):
o = StringIO.StringIO()
if t.arg == 'enumeration':
- print >> o, '// typedef for typedef %s:%s'\
- % (prefix, type_name_org)
- print >> o, 'type %s string' % (type_name)
-
- const_prefix = convert_const_prefix(type_name_org)
- print >> o, 'const ('
- m = {}
- for sub in t.substmts:
- enum_name = '%s_%s' % (const_prefix, convert_const_prefix(sub.arg))
- m[sub.arg.lower()] = enum_name
- print >> o, ' %s %s = "%s"' % (enum_name, type_name, sub.arg.lower())
- print >> o, ')\n'
-
- print >> o, 'func (v %s) ToInt() int {' % (type_name)
- print >> o, 'for i, vv := range []string{%s} {' % (",".join('"%s"' % s.arg.lower() for s in t.substmts))
- print >> o, 'if string(v) == vv {return i}'
- print >> o, '}'
- print >> o, 'return -1'
- print >> o, '}\n'
-
- print >> o, 'func (v %s) FromInt(i int) %s {' % (type_name, type_name)
- print >> o, 'for j, vv := range []string{%s} {' % (",".join('"%s"' % s.arg.lower() for s in t.substmts))
- print >> o, 'if i == j {return %s(vv)}' % (type_name)
- print >> o, '}'
- print >> o, 'return %s("")' % (type_name)
- print >> o, '}\n'
-
- print >> o, 'func (v %s) Validate() error {' % (type_name)
- print >> o, 'if v.ToInt() < 0 {'
- print >> o, 'return fmt.Errorf("invalid %s: %%s", v)' % (type_name)
- print >> o, '}'
- print >> o, 'return nil'
- print >> o, '}\n'
-
- if stmt.search_one('default'):
- default = stmt.search_one('default')
- print >> o, 'func (v %s) Default() %s {' % (type_name, type_name)
- print >> o, 'return %s' % m[default.arg.lower()]
- print >> o, '}\n'
-
- print >> o, 'func (v %s) DefaultAsNeeded() %s {' % (type_name, type_name)
- print >> o, ' if string(v) == "" {'
- print >> o, ' return v.Default()'
- print >> o, '}'
- print >> o, ' return v'
- print >> o, '}'
-
-
-
+ emit_enum(prefix, type_name_org, stmt, t.substmts)
elif t.arg == 'union':
print >> o, '// typedef for typedef %s:%s'\
% (prefix, type_name_org)
@@ -497,29 +526,18 @@ def emit_identity(ctx, module):
prefix = module.i_prefix
i_map = ctx.golang_identity_map[prefix]
for name, stmt in i_map.items():
- type_name_org = name
- type_name = stmt.golang_name
- base = stmt.search_one('base')
- o = StringIO.StringIO()
-
- print >> o, '// typedef for identity %s:%s' % (prefix, type_name_org)
- print >> o, 'type %s struct {' % (type_name)
- if base is not None:
- base_obj = lookup_identity(ctx, prefix, base.arg)
- print >> o, ' // base_type -> %s' % (base.arg)
- print >> o, ' %s' % (base_obj.golang_name)
-
- print >> o, '}'
- print o.getvalue()
-
+ enums = stmt.search('identity')
+ if len(enums) > 0:
+ emit_enum(prefix, name, stmt, enums)
def is_reference(s):
return s.arg in ['leafref', 'identityref']
-
def is_leafref(s):
return s.arg in ['leafref']
+def is_identityref(s):
+ return s.arg in ['identityref']
def is_leaf(s):
return s.keyword in ['leaf']
@@ -563,7 +581,6 @@ _type_translation_map = {
'inet:ipv4-address': 'string',
'inet:as-number': 'uint32',
'bgp-set-community-option-type': 'string',
- 'identityref' : 'string',
'inet:port-number': 'uint16',
'yang:timeticks': 'int64',
'ptypes:install-protocol-type': 'string',
diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang
index 1cf34800..29e3342d 100644
--- a/tools/pyang_plugins/gobgp.yang
+++ b/tools/pyang_plugins/gobgp.yang
@@ -9,6 +9,7 @@ module gobgp {
// import some basic types
import openconfig-bgp { prefix bgp; }
+ import openconfig-bgp-types { prefix bgp-types; }
import openconfig-routing-policy {prefix rpol; }
import openconfig-policy-types {prefix ptypes; }
import openconfig-bgp-policy {prefix bgp-pol; }
@@ -49,6 +50,74 @@ module gobgp {
}
}
+ identity eq {
+ base ptypes:attribute-comparison;
+ }
+
+ identity ge {
+ base ptypes:attribute-comparison;
+ }
+
+ identity le {
+ base ptypes:attribute-comparison;
+ }
+
+ identity IPV4-MULTICAST {
+ base bgp-types:afi-safi-type;
+ description
+ "IPv4 multicast (AFI,SAFI = 1,2)";
+ reference "RFC4760";
+ }
+
+ identity IPV6-MULTICAST {
+ base bgp-types:afi-safi-type;
+ description
+ "IPv4 multicast (AFI,SAFI = 1,2)";
+ reference "RFC4760";
+ }
+
+ identity RTC {
+ base bgp-types:afi-safi-type;
+ description
+ "Route target membership (AFI,SAFI = 1,132)";
+ reference "RFC4684";
+ }
+
+ identity ENCAP {
+ base bgp-types:afi-safi-type;
+ description
+ "Encapsulation (AFI,SAFI = 1,7)";
+ reference "RFC5512";
+ }
+
+ identity IPV4-FLOWSPEC {
+ base bgp-types:afi-safi-type;
+ description
+ "IPv4 flowspec (AFI,SAFI = 1,133)";
+ reference "RFC5575";
+ }
+
+ identity L3VPN-IPV4-FLOWSPEC {
+ base bgp-types:afi-safi-type;
+ description
+ "L3VPN IPv4 flowspec (AFI,SAFI = 1,134)";
+ reference "RFC5575";
+ }
+
+ identity IPV6-FLOWSPEC {
+ base bgp-types:afi-safi-type;
+ description
+ "IPv6 flowspec (AFI,SAFI = 1,133)";
+ reference "RFC5575";
+ }
+
+ identity L3VPN-IPV6-FLOWSPEC {
+ base bgp-types:afi-safi-type;
+ description
+ "L3VPN IPv6 flowspec (AFI,SAFI = 1,134)";
+ reference "RFC5575";
+ }
+
grouping gobgp-message-counter {
description
"Counters for all BGPMessage types";