diff options
author | Hiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp> | 2015-07-15 19:53:53 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-07-31 16:26:17 +0900 |
commit | 0b4b806c06f0ee50bb1bc1b30c38399553687abd (patch) | |
tree | 6898ec9eeb21a26668012c1c7743772da7b72214 /tools | |
parent | 2ad42ead02cce21cf71b3dde0731e8f5c6d4ac6a (diff) |
config: use the latest openconfig yang
Diffstat (limited to 'tools')
-rw-r--r-- | tools/config/example_toml.go | 156 | ||||
-rw-r--r-- | tools/pyang_plugins/bgpyang2golang.py | 147 | ||||
-rw-r--r-- | tools/route-server/quagga-rsconfig.go | 28 |
3 files changed, 247 insertions, 84 deletions
diff --git a/tools/config/example_toml.go b/tools/config/example_toml.go index 2be6b8e2..8a80e540 100644 --- a/tools/config/example_toml.go +++ b/tools/config/example_toml.go @@ -11,29 +11,50 @@ import ( func main() { b := config.Bgp{ Global: config.Global{ - As: 12332, - RouterId: net.ParseIP("10.0.0.1"), + GlobalConfig: config.GlobalConfig{ + As: 12332, + RouterId: net.ParseIP("10.0.0.1"), + }, }, - NeighborList: []config.Neighbor{ - config.Neighbor{ - PeerAs: 12333, - NeighborAddress: net.ParseIP("192.168.177.32"), - AuthPassword: "apple", - AfiSafiList: []config.AfiSafi{config.AfiSafi{AfiSafiName: "ipv4-unicast"}, config.AfiSafi{AfiSafiName: "ipv6-unicast"}}, - ApplyPolicy: config.ApplyPolicy{ - ImportPolicies: []string{"pd1"}, - DefaultImportPolicy: config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE, + Neighbors: config.Neighbors{ + NeighborList: []config.Neighbor{ + config.Neighbor{ + NeighborConfig: config.NeighborConfig{ + PeerAs: 12333, + AuthPassword: "apple", + NeighborAddress: net.ParseIP("192.168.177.33"), + }, + AfiSafis: config.AfiSafis{ + + AfiSafiList: []config.AfiSafi{ + config.AfiSafi{AfiSafiName: "ipv4-unicast"}, + config.AfiSafi{AfiSafiName: "ipv6-unicast"}, + }, + }, + ApplyPolicy: config.ApplyPolicy{ + + ApplyPolicyConfig: config.ApplyPolicyConfig{ + ImportPolicy: []string{"pd1"}, + DefaultImportPolicy: config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE, + }, + }, + }, + + config.Neighbor{ + NeighborConfig: config.NeighborConfig{ + PeerAs: 12334, + AuthPassword: "orange", + NeighborAddress: net.ParseIP("192.168.177.32"), + }, + }, + + config.Neighbor{ + NeighborConfig: config.NeighborConfig{ + PeerAs: 12335, + AuthPassword: "grape", + NeighborAddress: net.ParseIP("192.168.177.34"), + }, }, - }, - config.Neighbor{ - PeerAs: 12334, - NeighborAddress: net.ParseIP("192.168.177.33"), - AuthPassword: "orange", - }, - config.Neighbor{ - PeerAs: 12335, - NeighborAddress: net.ParseIP("192.168.177.34"), - AuthPassword: "grape", }, }, } @@ -54,12 +75,12 @@ func main() { func policy() config.RoutingPolicy { + _, prefix1, _ := net.ParseCIDR("10.3.192.0/21") ps := config.PrefixSet{ PrefixSetName: "ps1", PrefixList: []config.Prefix{ config.Prefix{ - Address: net.ParseIP("10.3.192.0"), - Masklength: 21, + IpPrefix: *prefix1, MasklengthRange: "21..24", }}, } @@ -74,55 +95,94 @@ func policy() config.RoutingPolicy { cs := config.CommunitySet{ CommunitySetName: "community1", - CommunityMembers: []string{"65100:10"}, + CommunityMember: []string{"65100:10"}, } ecs := config.ExtCommunitySet{ ExtCommunitySetName: "ecommunity1", - ExtCommunityMembers: []string{"RT:65001:200"}, + ExtCommunityMember: []string{"RT:65001:200"}, } as := config.AsPathSet{ - AsPathSetName: "aspath1", - AsPathSetMembers: []string{"^65100"}, + AsPathSetName: "aspath1", + AsPathSetMember: []string{"^65100"}, } bds := config.BgpDefinedSets{ - CommunitySetList: []config.CommunitySet{cs}, - ExtCommunitySetList: []config.ExtCommunitySet{ecs}, - AsPathSetList: []config.AsPathSet{as}, + + CommunitySets: config.CommunitySets{ + CommunitySetList: []config.CommunitySet{cs}, + }, + + ExtCommunitySets: config.ExtCommunitySets{ + ExtCommunitySetList: []config.ExtCommunitySet{ecs}, + }, + + AsPathSets: config.AsPathSets{ + AsPathSetList: []config.AsPathSet{as}, + }, } ds := config.DefinedSets{ - PrefixSetList: []config.PrefixSet{ps}, - NeighborSetList: []config.NeighborSet{ns}, + + PrefixSets: config.PrefixSets{ + PrefixSetList: []config.PrefixSet{ps}, + }, + + NeighborSets: config.NeighborSets{ + NeighborSetList: []config.NeighborSet{ns}, + }, + BgpDefinedSets: bds, } al := config.AsPathLength{ Operator: "eq", - Value: 2, + Value: 2, } s := config.Statement{ Name: "statement1", Conditions: config.Conditions{ - MatchPrefixSet: "ps1", - MatchNeighborSet: "ns1", - MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ALL, + + MatchPrefixSet: config.MatchPrefixSet{ + PrefixSet: "ps1", + MatchSetOptions: config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY, + }, + + MatchNeighborSet: config.MatchNeighborSet{ + NeighborSet: "ns1", + MatchSetOptions: config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY, + }, + BgpConditions: config.BgpConditions{ - MatchCommunitySet: "community1", - MatchExtCommunitySet: "ecommunity1", - MatchAsPathSet: "aspath1", + MatchCommunitySet: config.MatchCommunitySet{ + CommunitySet: "community1", + MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY, + }, + + MatchExtCommunitySet: config.MatchExtCommunitySet{ + ExtCommunitySet: "ecommunity1", + MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY, + }, + + MatchAsPathSet: config.MatchAsPathSet{ + AsPathSet: "aspath1", + MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY, + }, AsPathLength: al, }, }, Actions: config.Actions{ - AcceptRoute: false, - RejectRoute: true, + RouteDisposition: config.RouteDisposition{ + AcceptRoute: false, + RejectRoute: true, + }, BgpActions: config.BgpActions{ SetCommunity: config.SetCommunity{ - Communities: []string{"65100:20"}, + SetCommunityMethod: config.SetCommunityMethod{ + Communities: []string{"65100:20"}, + }, Options: "ADD", }, SetMed: "-200", @@ -131,13 +191,17 @@ func policy() config.RoutingPolicy { } pd := config.PolicyDefinition{ - Name: "pd1", - StatementList: []config.Statement{s}, + Name: "pd1", + Statements: config.Statements{ + StatementList: []config.Statement{s}, + }, } p := config.RoutingPolicy{ - DefinedSets: ds, - PolicyDefinitionList: []config.PolicyDefinition{pd}, + DefinedSets: ds, + PolicyDefinitions: config.PolicyDefinitions{ + PolicyDefinitionList: []config.PolicyDefinition{pd}, + }, } return p diff --git a/tools/pyang_plugins/bgpyang2golang.py b/tools/pyang_plugins/bgpyang2golang.py index c5912bda..9fe8a8ee 100644 --- a/tools/pyang_plugins/bgpyang2golang.py +++ b/tools/pyang_plugins/bgpyang2golang.py @@ -75,14 +75,15 @@ class GolangPlugin(plugin.PyangPlugin): # load augment module if ctx.opts.augment: aug_mod_path = ctx.opts.augment - try: - fd = open(aug_mod_path) - text = fd.read() - except IOError as ex: - sys.stderr.write("error %s: %s\n" % (aug_mod_path, str(ex))) - sys.exit(1) - aug_mod = ctx.add_module(aug_mod_path, text) - check_module_deps(ctx, aug_mod) + for p in aug_mod_path.split(","): + with open(p) as fd: + try: + text = fd.read() + except IOError as ex: + sys.stderr.write("error %s: %s\n" % (aug_mod_path, str(ex))) + sys.exit(1) + aug_mod = ctx.add_module(p, text) + check_module_deps(ctx, aug_mod) # visit yang statements visit_modules(ctx) @@ -115,7 +116,7 @@ def emit_go(ctx): emit_typedef(ctx, mod) for struct in ctx.golang_struct_def: - struct_name = struct.arg + struct_name = struct.uniq_name if struct_name in done: continue emit_class_def(ctx, struct, struct_name, struct.module_prefix) @@ -136,13 +137,21 @@ def check_module_deps(ctx, module): ctx.module_deps.append(mod) +def dig_leafref(type_obj): + reftype = type_obj.i_type_spec.i_target_node.search_one('type') + if is_leafref(reftype): + return dig_leafref(reftype) + else: + return reftype + + def emit_class_def(ctx, yang_statement, struct_name, prefix): o = StringIO.StringIO() - print >> o, '//struct for container %s:%s' % (prefix, struct_name) + print >> o, '//struct for container %s:%s' % (prefix, yang_statement.arg) print >> o, 'type %s struct {' % convert_to_golang(struct_name) for child in yang_statement.i_children: - container_or_list_name = child.arg + container_or_list_name = child.uniq_name val_name_go = convert_to_golang(child.arg) child_prefix = get_orig_prefix(child.i_orig_module) print >> o, ' // original -> %s:%s' % \ @@ -153,14 +162,21 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix): type_obj = child.search_one('type') type_name = type_obj.arg + # case identityref if type_name == 'identityref': emit_type_name = 'string' # case leafref elif type_name == 'leafref': - t = type_obj.i_type_spec.i_target_node.search_one('type') - emit_type_name = t.arg + t = dig_leafref(type_obj) + if is_translation_required(t): + print >> o, ' //%s:%s\'s original type is %s' \ + % (child_prefix, container_or_list_name, t.arg) + emit_type_name = translate_type(t.arg) + else: + emit_type_name = t.arg + # case translation required elif is_translation_required(type_obj): @@ -176,8 +192,13 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix): else: base_module = type_obj.i_orig_module.i_prefix t = lookup_typedef(ctx, base_module, type_name) + # print(t) emit_type_name = t.golang_name + # case 'case' + if is_case(child): + continue + # case leaflist if is_leaflist(child): type_obj = child.search_one('type') @@ -204,7 +225,7 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix): emit_type_name = '[]'+t.golang_name # case container - elif is_container(child): + elif is_container(child) or is_choice(child): key = child_prefix+':'+container_or_list_name t = ctx.golang_struct_names[key] emit_type_name = t.golang_name @@ -235,19 +256,70 @@ def get_orig_prefix(module): def visit_children(ctx, module, children): for c in children: - prefix = get_orig_prefix(c.i_orig_module) + + prefix = '' + if is_case(c): + prefix = get_orig_prefix(c.parent.i_orig_module) + c.i_orig_module = c.parent.i_orig_module + else: + prefix = get_orig_prefix(c.i_orig_module) + + c.uniq_name = c.arg + if c.arg == 'config': + c.uniq_name = c.parent.uniq_name + '-config' + + if c.arg == 'state': + + c.uniq_name = c.parent.uniq_name + '-state' + + if c.arg == 'graceful-restart' and prefix == 'bgp-mp': + c.uniq_name = 'mp-graceful-restart' + t = c.search_one('type') - type_name = t.arg if t is not None else None - if is_list(c) or is_container(c): - c.golang_name = convert_to_golang(c.arg) - ctx.golang_struct_def.append(c) - c.module_prefix = prefix - ctx.golang_struct_names[prefix+':'+c.arg] = c + + if is_list(c) or is_container(c) or is_choice(c): + c.golang_name = convert_to_golang(c.uniq_name) + + if is_choice(c): + picks = pickup_choice(c) + c.i_children = picks + + if ctx.golang_struct_names.get(prefix+':'+c.uniq_name): + ext_c = ctx.golang_struct_names.get(prefix+':'+c.uniq_name) + ext_c_child_count = len(getattr(ext_c, "i_children")) + current_c_child_count = len(getattr(c, "i_children")) + if ext_c_child_count < current_c_child_count: + c.module_prefix = prefix + ctx.golang_struct_names[prefix+':'+c.uniq_name] = c + idx = ctx.golang_struct_def.index(ext_c) + ctx.golang_struct_def[idx] = c + else: + c.module_prefix = prefix + ctx.golang_struct_names[prefix+':'+c.uniq_name] = c + ctx.golang_struct_def.append(c) if hasattr(c, 'i_children'): visit_children(ctx, module, c.i_children) +def pickup_choice(c): + element = [] + for child in c.i_children: + if is_case(child): + element = element + child.i_children + + return element + + +def get_type_spec(stmt): + for s in stmt.substmts: + if hasattr(s, 'i_type_spec'): + type_sp = s.i_type_spec + return type_sp.name + + return None + + def visit_typedef(ctx, module): prefix = module.i_prefix child_map = {} @@ -258,6 +330,7 @@ def visit_typedef(ctx, module): if stmts.golang_name == 'PeerType': stmts.golang_name = 'PeerTypeDef' child_map[name] = stmts + ctx.golang_typedef_map[prefix] = child_map if ctx.prefix_rel[prefix] != prefix: ctx.golang_typedef_map[ctx.prefix_rel[prefix]] = child_map @@ -301,6 +374,11 @@ def emit_typedef(ctx, module): prefix = module.i_prefix t_map = ctx.golang_typedef_map[prefix] for name, stmt in t_map.items(): + + # skip identityref type because currently skip identity + if get_type_spec(stmt) == 'identityref': + continue + type_name_org = name type_name = stmt.golang_name if type_name in emitted_type_names: @@ -324,6 +402,7 @@ def emit_typedef(ctx, module): print >> o, 'const (' already_added_iota = False + already_added_type = False for sub in t.substmts: if sub.search_one('value'): enum_value = " = "+sub.search_one('value').arg @@ -333,8 +412,14 @@ def emit_typedef(ctx, module): else: enum_value = " = iota" already_added_iota = True + + enum_name = convert_const_prefix(sub.arg) - print >> o, ' %s_%s%s' % (const_prefix, enum_name, enum_value) + + t = type_name if not already_added_type else "" + already_added_type = True + + print >> o, ' %s_%s %s%s' % (const_prefix, enum_name, t, enum_value) print >> o, ')' elif t.arg == 'union': print >> o, '// typedef for typedef %s:%s'\ @@ -373,6 +458,10 @@ def is_reference(s): return s.arg in ['leafref', 'identityref'] +def is_leafref(s): + return s.arg in ['leafref'] + + def is_leaf(s): return s.keyword in ['leaf'] @@ -389,6 +478,14 @@ def is_container(s): return s.keyword in ['container'] +def is_case(s): + return s.keyword in ['case'] + + +def is_choice(s): + return s.keyword in ['choice'] + + def is_builtin_type(t): return t.arg in _type_builtin @@ -399,14 +496,18 @@ def is_translation_required(t): _type_translation_map = { 'union': 'string', - 'enumeration': 'string', + 'enumeration': 'uint32', 'decimal64': 'float64', 'boolean': 'bool', 'empty': 'bool', 'inet:ip-address': 'net.IP', + 'inet:ip-prefix': 'net.IPNet', 'inet:ipv4-address': 'net.IP', 'inet:as-number': 'uint32', 'bgp-set-community-option-type' : 'string', + 'identityref' : 'string', + 'inet:port-number': 'uint16', + 'yang:timeticks': 'int64', } diff --git a/tools/route-server/quagga-rsconfig.go b/tools/route-server/quagga-rsconfig.go index 421b1f77..a58e8601 100644 --- a/tools/route-server/quagga-rsconfig.go +++ b/tools/route-server/quagga-rsconfig.go @@ -34,11 +34,11 @@ func (qt *QuaggaConfig) Config() *bytes.Buffer { buf.WriteString("hostname bgpd\n") buf.WriteString("password zebra\n") - buf.WriteString(fmt.Sprintf("router bgp %d\n", qt.config.PeerAs)) + buf.WriteString(fmt.Sprintf("router bgp %d\n", qt.config.NeighborConfig.PeerAs)) buf.WriteString(fmt.Sprintf("bgp router-id 192.168.0.%d\n", qt.id)) buf.WriteString(fmt.Sprintf("network 192.168.%d.0/24\n", qt.id)) - buf.WriteString(fmt.Sprintf("neighbor %s remote-as %d\n", qt.serverIP, qt.gobgpConfig.As)) - buf.WriteString(fmt.Sprintf("neighbor %s password %s\n", qt.serverIP, qt.config.AuthPassword)) + buf.WriteString(fmt.Sprintf("neighbor %s remote-as %d\n", qt.serverIP, qt.gobgpConfig.GlobalConfig.As)) + buf.WriteString(fmt.Sprintf("neighbor %s password %s\n", qt.serverIP, qt.config.NeighborConfig.AuthPassword)) buf.WriteString("log file /var/log/quagga/bgpd.log") return buf } @@ -46,20 +46,18 @@ func (qt *QuaggaConfig) Config() *bytes.Buffer { func create_config_files(nr int, outputDir string) { quaggaConfigList := make([]*QuaggaConfig, 0) - gobgpConf := config.Bgp{ - Global: config.Global{ - As: 65000, - RouterId: net.ParseIP("192.168.255.1"), - }, - } + gobgpConf := config.Bgp{} + gobgpConf.Global.GlobalConfig.As = 65000 + gobgpConf.Global.GlobalConfig.RouterId = net.ParseIP("192.168.255.1") for i := 1; i < nr+1; i++ { - c := config.Neighbor{ - PeerAs: 65000 + uint32(i), - NeighborAddress: net.ParseIP(fmt.Sprintf("10.0.0.%d", i)), - AuthPassword: fmt.Sprintf("hoge%d", i), - } - gobgpConf.NeighborList = append(gobgpConf.NeighborList, c) + + c := config.Neighbor{} + c.NeighborConfig.PeerAs = 65000 + uint32(i) + c.NeighborConfig.NeighborAddress = net.ParseIP(fmt.Sprintf("10.0.0.%d", i)) + c.NeighborConfig.AuthPassword = fmt.Sprintf("hoge%d", i) + + gobgpConf.Neighbors.NeighborList = append(gobgpConf.Neighbors.NeighborList, c) q := NewQuaggaConfig(i, &gobgpConf.Global, &c, net.ParseIP("10.0.255.1")) quaggaConfigList = append(quaggaConfigList, q) os.Mkdir(fmt.Sprintf("%s/q%d", outputDir, i), 0755) |