package dynamicrouting import ( "encoding/json" "strconv" "strings" ) // BGPInstance represents global BGP settings (/routing bgp instance) type BGPInstance struct { Enabled bool `json:"enabled"` AS uint32 `json:"as"` RouterID string `json:"router_id"` HoldTime int `json:"hold_time"` // Default 180 KeepaliveTime int `json:"keepalive_time"` // Default 60 InFilter string `json:"in_filter,omitempty"` OutFilter string `json:"out_filter,omitempty"` RedistributeConnected bool `json:"redistribute_connected"` RedistributeStatic bool `json:"redistribute_static"` RedistributeOSPF bool `json:"redistribute_ospf"` Running bool `json:"running"` } // BGPPeer represents a BGP peer connection (/routing bgp connection / peer) type BGPPeer struct { ID string `json:"id"` Name string `json:"name"` Enabled bool `json:"enabled"` Comment string `json:"comment,omitempty"` Instance string `json:"instance,omitempty"` Template string `json:"template,omitempty"` LocalAS uint32 `json:"local_as,omitempty"` // Multi-Instance Local AS (if 0, uses global AS) RouterID string `json:"router_id,omitempty"` AFI string `json:"afi,omitempty"` // "ip", "ipv6" RemoteAddress string `json:"remote_address"` RemotePort int `json:"remote_port,omitempty"` RemoteAS uint32 `json:"remote_as"` RemoteAllowAS string `json:"remote_allow_as,omitempty"` LocalAddress string `json:"local_address,omitempty"` LocalPort int `json:"local_port,omitempty"` LocalRole string `json:"local_role,omitempty"` // ebgp, ibgp Password string `json:"password,omitempty"` // TCP MD5 Key Multihop bool `json:"multihop"` TxTTL int `json:"tx_ttl,omitempty"` RxMinTTL int `json:"rx_min_ttl,omitempty"` Connect bool `json:"connect"` Listen bool `json:"listen"` HoldTime int `json:"hold_time,omitempty"` KeepaliveTime int `json:"keepalive_time,omitempty"` UseBFD bool `json:"use_bfd,omitempty"` RoutingTable string `json:"routing_table,omitempty"` VRF string `json:"vrf,omitempty"` NoClientReflect bool `json:"no_client_reflect,omitempty"` RedistConnected bool `json:"redist_connected"` RedistStatic bool `json:"redist_static"` RedistOSPF bool `json:"redist_ospf"` RedistBGP bool `json:"redist_bgp"` RedistRIP bool `json:"redist_rip,omitempty"` RedistVPN bool `json:"redist_vpn,omitempty"` RedistDHCP bool `json:"redist_dhcp,omitempty"` RedistFantasy bool `json:"redist_fantasy,omitempty"` RedistModem bool `json:"redist_modem,omitempty"` RedistBgpMplsVpn bool `json:"redist_bgp_mpls_vpn,omitempty"` RedistSlaac bool `json:"redist_slaac,omitempty"` DefaultOriginate bool `json:"default_originate"` NetworkBlackhole bool `json:"network_blackhole,omitempty"` NoEarlyCut bool `json:"no_early_cut,omitempty"` KeepSentAttrs bool `json:"keep_sent_attrs,omitempty"` InputAffinity string `json:"input_affinity,omitempty"` OutputAffinity string `json:"output_affinity,omitempty"` NexthopChoice string `json:"nexthop_choice,omitempty"` // default, force-self NexthopSelf bool `json:"nexthop_self"` DefaultPrepend int `json:"default_prepend,omitempty"` AllowASIn int `json:"allow_as_in,omitempty"` RemovePrivateAS bool `json:"remove_private_as"` ASOverride bool `json:"as_override,omitempty"` IgnoreASPathLen bool `json:"ignore_as_path_len,omitempty"` InFilter string `json:"in_filter,omitempty"` // Routing Filter chain for incoming routes InAcceptNLRI string `json:"in_accept_nlri,omitempty"` InAcceptCommunities string `json:"in_accept_communities,omitempty"` InAcceptExtCommunities string `json:"in_accept_ext_communities,omitempty"` InAcceptLargeCommunities string `json:"in_accept_large_communities,omitempty"` InFilterCommunities string `json:"in_filter_communities,omitempty"` InFilterExtCommunities string `json:"in_filter_ext_communities,omitempty"` InFilterLargeCommunities string `json:"in_filter_large_communities,omitempty"` InFilterUnknown bool `json:"in_filter_unknown,omitempty"` OutFilter string `json:"out_filter,omitempty"` // Routing Filter chain for outgoing routes OutSelectionPolicy string `json:"out_selection_policy,omitempty"` OutputNetwork string `json:"output_network,omitempty"` OutputNetworks []string `json:"output_networks,omitempty"` // Dynamic [+] / [-] output networks Disabled bool `json:"disabled"` Passive bool `json:"passive"` // Runtime telemetry State string `json:"state,omitempty"` // Established, Active, Connect, Idle Uptime string `json:"uptime,omitempty"` PrefixReceived int `json:"prefix_received"` PrefixSent int `json:"prefix_sent"` } // BGPNetwork represents an advertised network (/routing bgp network) type BGPNetwork struct { ID string `json:"id"` Network string `json:"network"` // CIDR, e.g. 10.200.0.0/24 Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // BGPRoute represents an active BGP route type BGPRoute struct { Prefix string `json:"prefix"` NextHop string `json:"next_hop"` Metric int `json:"metric"` Weight int `json:"weight"` Path string `json:"path"` Origin string `json:"origin"` Best bool `json:"best"` } // OSPFInstance represents an OSPF instance (/routing ospf instance) type OSPFInstance struct { ID string `json:"id"` Name string `json:"name"` // Default "Default" Version int `json:"version"` // 2 or 3 (default 2) VRF string `json:"vrf"` // Default "main" RouterID string `json:"router_id"` // e.g. "10.42.62.254" RoutingTable string `json:"routing_table,omitempty"`// Default "main" Enabled bool `json:"enabled"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` InFilter string `json:"in_filter,omitempty"` OutFilter string `json:"out_filter,omitempty"` RedistributeConnected bool `json:"redistribute_connected"` RedistributeStatic bool `json:"redistribute_static"` RedistributeBGP bool `json:"redistribute_bgp"` RedistributeDefault bool `json:"redistribute_default"` // MikroTik redistribute-default OriginateDefault string `json:"originate_default,omitempty"` // "never", "if-installed", "always" DefaultMetric int `json:"default_metric"` Running bool `json:"running"` } // UnmarshalJSON supports both int (2, 3) and string ("2", "3", "ospfv2", "ospfv3") for Version. func (o *OSPFInstance) UnmarshalJSON(data []byte) error { type Alias OSPFInstance aux := struct { RawVersion interface{} `json:"version"` *Alias }{ Alias: (*Alias)(o), } if err := json.Unmarshal(data, &aux); err != nil { return err } switch v := aux.RawVersion.(type) { case float64: o.Version = int(v) case int: o.Version = v case string: vStr := strings.ToLower(strings.TrimSpace(v)) if strings.Contains(vStr, "3") || strings.Contains(vStr, "v3") || vStr == "ipv6" { o.Version = 3 } else if strings.Contains(vStr, "2") || strings.Contains(vStr, "v2") || vStr == "ipv4" { o.Version = 2 } else if parsed, err := strconv.Atoi(vStr); err == nil { o.Version = parsed } } if o.Version <= 0 { o.Version = 2 } return nil } // OSPFArea represents an OSPF area (/routing ospf area) type OSPFArea struct { ID string `json:"id"` Name string `json:"name"` // Default "Default" Instance string `json:"instance,omitempty"` // Default "Default" AreaID string `json:"area_id"` // e.g. "0.0.0.0" AreaType string `json:"area_type"` // default, stub, nssa DefaultCost int `json:"default_cost,omitempty"` NoSummaries bool `json:"no_summaries,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // OSPFAreaRange represents an area range (/routing ospf area range) type OSPFAreaRange struct { ID string `json:"id"` Area string `json:"area"` // Area name or ID Prefix string `json:"prefix"` // CIDR e.g. "10.42.0.0/16" Cost int `json:"cost"` Advertise bool `json:"advertise"` // default true Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // OSPFInterface represents an OSPF interface template (/routing ospf interface-template) type OSPFInterface struct { ID string `json:"id"` Interfaces string `json:"interfaces,omitempty"` // ether1, wlan1, all... Area string `json:"area"` // Area ID or name e.g. "Default" / "0.0.0.0" Networks string `json:"networks,omitempty"` // CIDR e.g. "10.42.36.244/30" NetworkType string `json:"network_type"` // broadcast, ptp, nbma, point-to-multipoint Cost int `json:"cost"` // Metric, default 1 Priority int `json:"priority"` // Default 128 HelloInterval int `json:"hello_interval"` // Default 10 DeadInterval int `json:"dead_interval"` // Default 40 Passive bool `json:"passive"` Auth string `json:"auth,omitempty"` // none, simple, md5 AuthKey string `json:"auth_key,omitempty"` UseBFD bool `json:"use_bfd,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` // Backward compatibility aliases Network string `json:"network,omitempty"` Interface string `json:"interface,omitempty"` AuthType string `json:"auth_type,omitempty"` } // OSPFInterfaceLive represents dynamic live OSPF interface state (/routing ospf interface) type OSPFInterfaceLive struct { Flags string `json:"flags"` // "D" (dynamic) Interface string `json:"interface"` // e.g. "eth0" Address string `json:"address"` // e.g. "192.168.131.0/24" Area string `json:"area"` // e.g. "Default" or "0.0.0.0" InstanceID int `json:"instance_id"` // 0 State string `json:"state"` // dr, backup, waiting, passive, ptp Cost int `json:"cost"` Priority int `json:"priority"` } // OSPFStaticNeighbor represents a static OSPF neighbor (/routing ospf static-neighbor) type OSPFStaticNeighbor struct { ID string `json:"id"` Address string `json:"address"` Area string `json:"area"` PollInterval int `json:"poll_interval"` Cost int `json:"cost"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // OSPFNeighbor represents a live OSPF neighbor (/routing ospf neighbor) type OSPFNeighbor struct { Flags string `json:"flags"` // "D" (dynamic) Comment string `json:"comment,omitempty"` Instance string `json:"instance"` // "Default" Area string `json:"area"` // "Default" Address string `json:"address"` // "10.42.62.249" State string `json:"state"` // "Full" StateChanges int `json:"state_changes"` // e.g. 6 NeighborID string `json:"neighbor_id,omitempty"` Interface string `json:"interface,omitempty"` DeadTimer string `json:"dead_timer,omitempty"` Priority int `json:"priority,omitempty"` } // OSPFLSA represents an LSA record in the Link-State Database (/routing ospf lsa) type OSPFLSA struct { Flags string `json:"flags"` // "D", "SD" Instance string `json:"instance"` // "Default" Area string `json:"area"` // "Default" Type string `json:"type"` // "router", "network", "as-external", "summary-net", "summary-asbr" Originator string `json:"originator"` // Router ID ID string `json:"id"` // LS ID Link string `json:"link"` LinkIndex int `json:"link_index"` Sequence string `json:"sequence"` // e.g. "8000006e" Age int `json:"age"` // seconds } // OSPFRoute represents an active OSPF route type OSPFRoute struct { Prefix string `json:"prefix"` RouteType string `json:"route_type"` // Intra-Area, Inter-Area, External Cost int `json:"cost"` Area string `json:"area"` NextHop string `json:"next_hop"` Interface string `json:"interface"` } // RoutingFilterRule represents a route filter rule (/routing filter rule) type RoutingFilterRule struct { ID string `json:"id"` Chain string `json:"chain"` // e.g. "bgp-in", "bgp-out", "isp-in" RuleOrder int `json:"rule_order"` // e.g. 10, 20, 30... Sequence number Rule string `json:"rule"` // RouterOS v7 rule script e.g. "if (dst in 10.0.0.0/8) { set bgp-local-pref 150; accept; }" Action string `json:"action"` // "accept" (permit), "discard" (deny), "reject", "passthrough" Prefix string `json:"prefix,omitempty"` // CIDR e.g. "10.0.0.0/8" or "0.0.0.0/0" PrefixLen string `json:"prefix_len,omitempty"` // e.g. "24-32", "ge 24 le 32", "24" MatchProtocol string `json:"match_protocol,omitempty"` // "any", "bgp", "ospf", "connected", "static" MatchASPath string `json:"match_as_path,omitempty"` // regex e.g. "^65000_" MatchCommunity string `json:"match_community,omitempty"`// e.g. "65001:100" SetLocalPref int `json:"set_local_pref,omitempty"` // BGP Local Preference SetMetric int `json:"set_metric,omitempty"` // BGP MED / OSPF Metric SetASPrepend int `json:"set_as_prepend,omitempty"` // AS Path prepend count SetCommunity string `json:"set_community,omitempty"` // Set BGP community SetNextHop string `json:"set_next_hop,omitempty"` // Custom Next Hop IP SetDistance int `json:"set_distance,omitempty"` // Administrative Distance Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // RoutingFilterSelectRule represents a deprecated route selection rule (/routing filter select-rule) type RoutingFilterSelectRule struct { ID string `json:"id"` Chain string `json:"chain"` RuleOrder int `json:"rule_order"` Rule string `json:"rule"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // RoutingFilterCommunityList represents a named community set (/routing filter community-list) type RoutingFilterCommunityList struct { ID string `json:"id"` Name string `json:"name"` Communities []string `json:"communities"` Regexp string `json:"regexp,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // RoutingFilterASList represents a named AS number list (/routing filter num-list) type RoutingFilterASList struct { ID string `json:"id"` Name string `json:"name"` Range string `json:"range"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // RIPInstance represents a RIP routing instance (/routing rip instance) type RIPInstance struct { ID string `json:"id"` Name string `json:"name"` // e.g. "default" Version int `json:"version"` // 2 for IPv4, 1 for RIPng IPv6 (default 2) VRF string `json:"vrf,omitempty"` // default "main" RoutingTable string `json:"routing_table,omitempty"`// default "main" Enabled bool `json:"enabled"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` InFilter string `json:"in_filter,omitempty"` OutFilter string `json:"out_filter,omitempty"` RedistributeConnected bool `json:"redistribute_connected"` RedistributeStatic bool `json:"redistribute_static"` RedistributeOSPF bool `json:"redistribute_ospf"` RedistributeBGP bool `json:"redistribute_bgp"` RedistributeDefault bool `json:"redistribute_default"` DefaultMetric int `json:"default_metric"` // default 1 UpdateTime int `json:"update_time"` // default 30 TimeoutTime int `json:"timeout_time"` // default 180 GarbageTime int `json:"garbage_time"` // default 120 Running bool `json:"running"` } // UnmarshalJSON supports both int (2, 1) and string ("2", "1", "rip2", "ripng") for Version. func (r *RIPInstance) UnmarshalJSON(data []byte) error { type Alias RIPInstance aux := struct { RawVersion interface{} `json:"version"` *Alias }{ Alias: (*Alias)(r), } if err := json.Unmarshal(data, &aux); err != nil { return err } switch v := aux.RawVersion.(type) { case float64: r.Version = int(v) case int: r.Version = v case string: vStr := strings.ToLower(strings.TrimSpace(v)) if strings.Contains(vStr, "ng") || strings.Contains(vStr, "v1") || vStr == "1" || vStr == "ipv6" { r.Version = 1 } else if strings.Contains(vStr, "2") || vStr == "ipv4" { r.Version = 2 } else if parsed, err := strconv.Atoi(vStr); err == nil { r.Version = parsed } } if r.Version == 0 { r.Version = 2 } return nil } // RIPInterface represents a RIP interface template (/routing rip interface) type RIPInterface struct { ID string `json:"id"` Instance string `json:"instance,omitempty"` Interface string `json:"interface"` // e.g. "eth0" or "*" Metric int `json:"metric"` // Metric/cost added (default 1) Mode string `json:"mode,omitempty"` // "multicast", "broadcast" (default multicast) Passive bool `json:"passive"` UseBFD bool `json:"use_bfd,omitempty"` Auth string `json:"auth,omitempty"` // "none", "simple", "md5" AuthKey string `json:"auth_key,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // RIPNeighbor represents an explicit RIP neighbor (/routing rip neighbor) type RIPNeighbor struct { ID string `json:"id"` Instance string `json:"instance,omitempty"` Address string `json:"address"` // Neighbor IP Interface string `json:"interface,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // RIPNeighborLive represents a live RIP neighbor detected by BIRD type RIPNeighborLive struct { Address string `json:"address"` Interface string `json:"interface"` Uptime string `json:"uptime"` LastSeen string `json:"last_seen"` } // RIPRoute represents an active RIP route learned or advertised type RIPRoute struct { Prefix string `json:"prefix"` NextHop string `json:"next_hop"` Metric int `json:"metric"` Interface string `json:"interface"` Uptime string `json:"uptime"` } // BFDInstance represents global BFD settings (/routing bfd instance) type BFDInstance struct { Enabled bool `json:"enabled"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` Running bool `json:"running"` } // BFDInterface represents a BFD interface template (/routing bfd interface) type BFDInterface struct { ID string `json:"id"` Interface string `json:"interface"` // e.g. "eth0" or "*" MinRxInterval int `json:"min_rx_interval"` // ms, default 100 MinTxInterval int `json:"min_tx_interval"` // ms, default 100 IdleTxInterval int `json:"idle_tx_interval,omitempty"`// ms, default 1000 Multiplier int `json:"multiplier"` // default 3 Passive bool `json:"passive"` Auth string `json:"auth,omitempty"` // "none", "simple", "meticulous keyed sha1" AuthKey string `json:"auth_key,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // BFDNeighbor represents an explicit BFD neighbor / peer (/routing bfd peer) type BFDNeighbor struct { ID string `json:"id"` Address string `json:"address"` Interface string `json:"interface,omitempty"` LocalAddress string `json:"local_address,omitempty"` Multihop bool `json:"multihop"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // BFDSession represents a live BFD session (/routing bfd session) type BFDSession struct { IP string `json:"ip"` Interface string `json:"interface"` State string `json:"state"` // "Up", "Down", "Init", "AdminDown" Since string `json:"since"` Interval string `json:"interval"` Timeout string `json:"timeout"` } // BabelInstance represents a Babel instance (/routing babel instance) type BabelInstance struct { ID string `json:"id"` Name string `json:"name"` // "default" RouterID string `json:"router_id,omitempty"` VRF string `json:"vrf,omitempty"` RoutingTable string `json:"routing_table,omitempty"` Enabled bool `json:"enabled"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` InFilter string `json:"in_filter,omitempty"` OutFilter string `json:"out_filter,omitempty"` RedistributeConnected bool `json:"redistribute_connected"` RedistributeStatic bool `json:"redistribute_static"` RedistributeOSPF bool `json:"redistribute_ospf"` RedistributeBGP bool `json:"redistribute_bgp"` RedistributeDefault bool `json:"redistribute_default"` DefaultMetric int `json:"default_metric"` Running bool `json:"running"` } // BabelInterface represents a Babel interface template (/routing babel interface) type BabelInterface struct { ID string `json:"id"` Instance string `json:"instance,omitempty"` Interface string `json:"interface"` // "eth0" or "*" Type string `json:"type,omitempty"` // "wired", "wireless" (default "wired") RxCost int `json:"rxcost,omitempty"` // default 10 or 96 HelloInterval int `json:"hello_interval,omitempty"` // default 4 s UpdateInterval int `json:"update_interval,omitempty"` // default 16 s Auth string `json:"auth,omitempty"` // "none", "mac" AuthKey string `json:"auth_key,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // BabelNeighbor represents a live Babel neighbor (/routing babel neighbor) type BabelNeighbor struct { IP string `json:"ip"` Interface string `json:"interface"` Metric int `json:"metric"` Cost int `json:"cost,omitempty"` Routes int `json:"routes,omitempty"` Hellos int `json:"hellos,omitempty"` Uptime string `json:"uptime,omitempty"` Expires string `json:"expires,omitempty"` Auth string `json:"auth,omitempty"` RTT float64 `json:"rtt,omitempty"` } // BabelRoute represents an active Babel route (/routing babel route) type BabelRoute struct { Prefix string `json:"prefix"` NextHop string `json:"next_hop"` Metric int `json:"metric"` Interface string `json:"interface"` Flag string `json:"flag,omitempty"` Seqno int `json:"seqno,omitempty"` Expires string `json:"expires,omitempty"` } // BabelInterfaceLive represents a running Babel interface reported by BIRD (/routing babel interface) type BabelInterfaceLive struct { Instance string `json:"instance"` Interface string `json:"interface"` State string `json:"state"` Auth string `json:"auth"` RxCost int `json:"rxcost"` Neighbors int `json:"neighbors"` Timer string `json:"timer"` NextHopV4 string `json:"next_hop_v4"` NextHopV6 string `json:"next_hop_v6"` } // RAdvInstance represents an IPv6 Router Advertisement instance (/routing radv instance) type RAdvInstance struct { ID string `json:"id"` Name string `json:"name"` // "default" Enabled bool `json:"enabled"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` Running bool `json:"running"` } // RAdvInterface represents a RAdv interface (/routing radv interface) type RAdvInterface struct { ID string `json:"id"` Instance string `json:"instance,omitempty"` Interface string `json:"interface"` MinRAInterval int `json:"min_ra_interval,omitempty"` // default 200 s MaxRAInterval int `json:"max_ra_interval,omitempty"` // default 600 s DefaultLifetime int `json:"default_lifetime,omitempty"` // default 1800 s HopLimit int `json:"hop_limit,omitempty"` // default 64 Prefixes []string `json:"prefixes,omitempty"` // IPv6 prefixes e.g. ["2001:db8::/64"] RDNSS []string `json:"rdnss,omitempty"` // IPv6 DNS servers e.g. ["2001:4860:4860::8888"] Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // EIGRPInstance represents an EIGRP routing instance (/routing eigrp instance) type EIGRPInstance struct { ID string `json:"id"` Name string `json:"name"` // e.g. "default", "eigrp100" AS int `json:"as"` // Autonomous System number, default 100 RouterID string `json:"router_id,omitempty"` // e.g. "192.168.131.56" VRF string `json:"vrf,omitempty"` // default "main" Enabled bool `json:"enabled"` Disabled bool `json:"disabled"` Running bool `json:"running"` Comment string `json:"comment,omitempty"` InFilter string `json:"in_filter,omitempty"` OutFilter string `json:"out_filter,omitempty"` RedistributeConnected bool `json:"redistribute_connected"` RedistributeStatic bool `json:"redistribute_static"` RedistributeOSPF bool `json:"redistribute_ospf"` RedistributeBGP bool `json:"redistribute_bgp"` RedistributeDefault bool `json:"redistribute_default"` Variance int `json:"variance,omitempty"` // default 1 MaximumPaths int `json:"maximum_paths,omitempty"` // default 4 DefaultMetric int `json:"default_metric,omitempty"` K1 int `json:"k1"` // default 1 K2 int `json:"k2"` // default 0 K3 int `json:"k3"` // default 1 K4 int `json:"k4"` // default 0 K5 int `json:"k5"` // default 0 } // UnmarshalJSON supports both int and string for AS and numeric fields. func (e *EIGRPInstance) UnmarshalJSON(data []byte) error { type Alias EIGRPInstance aux := struct { RawAS interface{} `json:"as"` *Alias }{ Alias: (*Alias)(e), } if err := json.Unmarshal(data, &aux); err != nil { return err } switch v := aux.RawAS.(type) { case float64: e.AS = int(v) case int: e.AS = v case string: if parsed, err := strconv.Atoi(strings.TrimSpace(v)); err == nil { e.AS = parsed } } if e.AS == 0 { e.AS = 100 } if e.Variance == 0 { e.Variance = 1 } if e.MaximumPaths == 0 { e.MaximumPaths = 4 } return nil } // EIGRPInterface represents an EIGRP interface template (/routing eigrp interface) type EIGRPInterface struct { ID string `json:"id"` Instance string `json:"instance,omitempty"` // Instance Name or AS Interface string `json:"interface"` // e.g. "eth0" or "*" HelloInterval int `json:"hello_interval,omitempty"`// Default 5s HoldTime int `json:"hold_time,omitempty"` // Default 15s Passive bool `json:"passive"` SplitHorizon bool `json:"split_horizon"` // Default true AuthMode string `json:"auth_mode,omitempty"` // "none", "md5" AuthKey string `json:"auth_key,omitempty"` Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // EIGRPNetwork represents a network network command under EIGRP (/routing eigrp network) type EIGRPNetwork struct { ID string `json:"id"` Instance string `json:"instance,omitempty"` Network string `json:"network"` // CIDR, e.g. "192.168.131.0/24" Disabled bool `json:"disabled"` Comment string `json:"comment,omitempty"` } // EIGRPNeighborLive represents a live EIGRP neighbor reported by FRR (/routing eigrp neighbor) type EIGRPNeighborLive struct { AS int `json:"as"` Address string `json:"address"` Interface string `json:"interface"` HoldTime int `json:"hold_time"` Uptime string `json:"uptime"` SRTT int `json:"srtt"` RTO int `json:"rto"` SeqNum int `json:"seq_num"` } // EIGRPRouteLive represents a route in the EIGRP topology table (/routing eigrp topology) type EIGRPRouteLive struct { AS int `json:"as"` Prefix string `json:"prefix"` Successors int `json:"successors"` Distance int `json:"distance"` // Feasible Distance (FD) NextHop string `json:"next_hop"` Interface string `json:"interface"` State string `json:"state"` // "P" (Passive), "A" (Active) } // DynamicRoutingSummary aggregates status for dashboard & badges type DynamicRoutingSummary struct { BGPEnabled bool `json:"bgp_enabled"` BGPRunning bool `json:"bgp_running"` BGPPeerCount int `json:"bgp_peer_count"` BGPEstablishedCount int `json:"bgp_established_count"` OSPFEnabled bool `json:"ospf_enabled"` OSPFRunning bool `json:"ospf_running"` OSPFNeighborCount int `json:"ospf_neighbor_count"` OSPFAdjacentCount int `json:"ospf_adjacent_count"` RIPEnabled bool `json:"rip_enabled"` RIPRunning bool `json:"rip_running"` RIPNeighborCount int `json:"rip_neighbor_count"` BFDEnabled bool `json:"bfd_enabled"` BFDRunning bool `json:"bfd_running"` BFDSessionCount int `json:"bfd_session_count"` BabelEnabled bool `json:"babel_enabled"` BabelRunning bool `json:"babel_running"` BabelNeighborCount int `json:"babel_neighbor_count"` RAdvEnabled bool `json:"radv_enabled"` RAdvRunning bool `json:"radv_running"` EIGRPEnabled bool `json:"eigrp_enabled"` EIGRPRunning bool `json:"eigrp_running"` EIGRPNeighborCount int `json:"eigrp_neighbor_count"` RoutingFilterCount int `json:"routing_filter_count"` } // DynamicConfig stores all dynamic routing data on disk type DynamicConfig struct { BGPInstance BGPInstance `json:"bgp_instance"` BGPPeers []BGPPeer `json:"bgp_peers"` BGPNetworks []BGPNetwork `json:"bgp_networks"` OSPFInstances []OSPFInstance `json:"ospf_instances"` OSPFInstance OSPFInstance `json:"ospf_instance"` // Backward compatibility OSPFAreas []OSPFArea `json:"ospf_areas"` OSPFAreaRanges []OSPFAreaRange `json:"ospf_area_ranges"` OSPFInterfaces []OSPFInterface `json:"ospf_interfaces"` OSPFStaticNbrs []OSPFStaticNeighbor `json:"ospf_static_nbrs"` RIPInstances []RIPInstance `json:"rip_instances"` RIPInterfaces []RIPInterface `json:"rip_interfaces"` RIPNeighbors []RIPNeighbor `json:"rip_neighbors"` BFDInstance BFDInstance `json:"bfd_instance"` BFDInterfaces []BFDInterface `json:"bfd_interfaces"` BFDNeighbors []BFDNeighbor `json:"bfd_neighbors"` BabelInstances []BabelInstance `json:"babel_instances"` BabelInterfaces []BabelInterface `json:"babel_interfaces"` RAdvInstances []RAdvInstance `json:"radv_instances"` RAdvInterfaces []RAdvInterface `json:"radv_interfaces"` EIGRPInstances []EIGRPInstance `json:"eigrp_instances"` EIGRPInterfaces []EIGRPInterface `json:"eigrp_interfaces"` EIGRPNetworks []EIGRPNetwork `json:"eigrp_networks"` RoutingFilters []RoutingFilterRule `json:"routing_filters"` RoutingSelectRules []RoutingFilterSelectRule `json:"routing_select_rules,omitempty"` // Deprecated: unused in BIRD 2 RoutingCommunityLists []RoutingFilterCommunityList `json:"routing_community_lists"` RoutingASLists []RoutingFilterASList `json:"routing_as_lists"` }