Files
EvoBGP/internal/birdfmt/layout.go
T

96 lines
2.5 KiB
Go

package birdfmt
import (
"fmt"
"strings"
)
// Directory and fragment file names for EvoBGP-generated includes (relative to bird.conf).
const (
DirBirdD = "bird.d"
FragmentPrefixesV4 = "evobgp_prefixes_v4.conf"
FragmentPrefixesV6 = "evobgp_prefixes_v6.conf"
FragmentFiltersV4 = "evobgp_filters_v4.conf"
FragmentFiltersV6 = "evobgp_filters_v6.conf"
FragmentPeers = "evobgp_peers.conf"
)
// FragmentIncludePath returns a POSIX include path such as bird.d/evobgp_prefixes_v4.conf.
func FragmentIncludePath(fragmentBaseName string) string {
if fragmentBaseName == "" {
return DirBirdD + "/"
}
return DirBirdD + "/" + fragmentBaseName
}
// StandardIncludeFragments is the recommended order: filters before peers that reference them.
func StandardIncludeFragments() []string {
return []string{
FragmentIncludePath(FragmentFiltersV4),
FragmentIncludePath(FragmentFiltersV6),
FragmentIncludePath(FragmentPrefixesV4),
FragmentIncludePath(FragmentPrefixesV6),
FragmentIncludePath(FragmentPeers),
}
}
// MainBirdConfOptions describes the top-level bird.conf skeleton EvoBGP expects beside bird.d/.
type MainBirdConfOptions struct {
// RouterID is the BIRD router id (IPv4 dotted quad recommended).
RouterID string
// Includes are paths as in include "…" (e.g. bird.d/evobgp_prefixes_v4.conf).
Includes []string
// Preamble is optional comment lines (each line prefixed with #), no trailing newline required.
Preamble string
}
// RenderMainBirdConf returns a BIRD 2 main config: device, direct, include lines.
// RouterID must be non-empty.
func RenderMainBirdConf(opts MainBirdConfOptions) (string, error) {
if strings.TrimSpace(opts.RouterID) == "" {
return "", fmt.Errorf("birdfmt: router id is required")
}
var b strings.Builder
pre := strings.TrimSpace(opts.Preamble)
if pre != "" {
for _, line := range strings.Split(pre, "\n") {
line = strings.TrimRight(line, "\r")
if line == "" {
b.WriteByte('\n')
continue
}
if !strings.HasPrefix(line, "#") {
b.WriteString("# ")
}
b.WriteString(line)
b.WriteByte('\n')
}
b.WriteByte('\n')
}
b.WriteString("router id ")
b.WriteString(strings.TrimSpace(opts.RouterID))
b.WriteString(";\n\n")
for _, inc := range opts.Includes {
inc = strings.TrimSpace(inc)
if inc == "" {
continue
}
b.WriteString("include \"")
b.WriteString(inc)
b.WriteString("\";\n")
}
if len(opts.Includes) > 0 {
b.WriteByte('\n')
}
b.WriteString(`protocol device {
}
protocol direct {
ipv4;
ipv6;
}
`)
return b.String(), nil
}