115 lines
3.5 KiB
Go
115 lines
3.5 KiB
Go
package birdfmt
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// BGPPeerIPv4Options describes a single BGP session (BIRD 2, IPv4 AF).
|
|
type BGPPeerIPv4Options struct {
|
|
ProtocolName string // e.g. evobgp_peer_uplink
|
|
LocalIP string // e.g. 192.0.2.1
|
|
LocalASN uint32
|
|
NeighborIP string
|
|
NeighborASN uint32
|
|
// ExportFilter is a filter name, or empty for "export all".
|
|
ExportFilter string
|
|
// ImportFilter is a filter name, or empty for "import all".
|
|
ImportFilter string
|
|
}
|
|
|
|
// RenderProtocolBGPIPv4 renders a protocol bgp { … ipv4 { … } } block.
|
|
func RenderProtocolBGPIPv4(opts BGPPeerIPv4Options) (string, error) {
|
|
if strings.TrimSpace(opts.ProtocolName) == "" {
|
|
return "", fmt.Errorf("birdfmt: protocol name is required")
|
|
}
|
|
if strings.TrimSpace(opts.LocalIP) == "" || strings.TrimSpace(opts.NeighborIP) == "" {
|
|
return "", fmt.Errorf("birdfmt: local and neighbor addresses are required")
|
|
}
|
|
if opts.LocalASN == 0 || opts.NeighborASN == 0 {
|
|
return "", fmt.Errorf("birdfmt: AS numbers must be non-zero")
|
|
}
|
|
imp := "all"
|
|
if strings.TrimSpace(opts.ImportFilter) != "" {
|
|
imp = "filter " + strings.TrimSpace(opts.ImportFilter)
|
|
}
|
|
exp := "all"
|
|
if strings.TrimSpace(opts.ExportFilter) != "" {
|
|
exp = "filter " + strings.TrimSpace(opts.ExportFilter)
|
|
}
|
|
|
|
var b strings.Builder
|
|
b.WriteString("protocol bgp ")
|
|
b.WriteString(strings.TrimSpace(opts.ProtocolName))
|
|
b.WriteString(" {\n")
|
|
b.WriteString(" local ")
|
|
b.WriteString(strings.TrimSpace(opts.LocalIP))
|
|
fmt.Fprintf(&b, " as %d;\n", opts.LocalASN)
|
|
b.WriteString(" neighbor ")
|
|
b.WriteString(strings.TrimSpace(opts.NeighborIP))
|
|
fmt.Fprintf(&b, " as %d;\n", opts.NeighborASN)
|
|
b.WriteString(" ipv4 {\n")
|
|
b.WriteString(" import ")
|
|
b.WriteString(imp)
|
|
b.WriteString(";\n")
|
|
b.WriteString(" export ")
|
|
b.WriteString(exp)
|
|
b.WriteString(";\n")
|
|
b.WriteString(" };\n")
|
|
b.WriteString("}\n")
|
|
return b.String(), nil
|
|
}
|
|
|
|
// BGPPeerIPv6Options describes a BGP session for the IPv6 AF.
|
|
type BGPPeerIPv6Options struct {
|
|
ProtocolName string
|
|
LocalIP string
|
|
LocalASN uint32
|
|
NeighborIP string
|
|
NeighborASN uint32
|
|
ExportFilter string
|
|
ImportFilter string
|
|
}
|
|
|
|
// RenderProtocolBGPIPv6 renders a protocol bgp block with ipv6 { import/export }.
|
|
func RenderProtocolBGPIPv6(opts BGPPeerIPv6Options) (string, error) {
|
|
if strings.TrimSpace(opts.ProtocolName) == "" {
|
|
return "", fmt.Errorf("birdfmt: protocol name is required")
|
|
}
|
|
if strings.TrimSpace(opts.LocalIP) == "" || strings.TrimSpace(opts.NeighborIP) == "" {
|
|
return "", fmt.Errorf("birdfmt: local and neighbor addresses are required")
|
|
}
|
|
if opts.LocalASN == 0 || opts.NeighborASN == 0 {
|
|
return "", fmt.Errorf("birdfmt: AS numbers must be non-zero")
|
|
}
|
|
imp := "all"
|
|
if strings.TrimSpace(opts.ImportFilter) != "" {
|
|
imp = "filter " + strings.TrimSpace(opts.ImportFilter)
|
|
}
|
|
exp := "all"
|
|
if strings.TrimSpace(opts.ExportFilter) != "" {
|
|
exp = "filter " + strings.TrimSpace(opts.ExportFilter)
|
|
}
|
|
|
|
var b strings.Builder
|
|
b.WriteString("protocol bgp ")
|
|
b.WriteString(strings.TrimSpace(opts.ProtocolName))
|
|
b.WriteString(" {\n")
|
|
b.WriteString(" local ")
|
|
b.WriteString(strings.TrimSpace(opts.LocalIP))
|
|
fmt.Fprintf(&b, " as %d;\n", opts.LocalASN)
|
|
b.WriteString(" neighbor ")
|
|
b.WriteString(strings.TrimSpace(opts.NeighborIP))
|
|
fmt.Fprintf(&b, " as %d;\n", opts.NeighborASN)
|
|
b.WriteString(" ipv6 {\n")
|
|
b.WriteString(" import ")
|
|
b.WriteString(imp)
|
|
b.WriteString(";\n")
|
|
b.WriteString(" export ")
|
|
b.WriteString(exp)
|
|
b.WriteString(";\n")
|
|
b.WriteString(" };\n")
|
|
b.WriteString("}\n")
|
|
return b.String(), nil
|
|
}
|