refactor: remove strict bind configuration from BGP templates and update related logic. Eliminate 'strict bind on' from both IPv4 and IPv6 templates to simplify BGP peer rendering. Adjust OpenAPI documentation and internal handling of BGP source addresses to reflect these changes, enhancing clarity and compatibility.
CI / changes (push) Successful in 7s
CI / openapi (push) Successful in 23s
CI / go (push) Successful in 24s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m7s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m2s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 55s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 54s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 2m19s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 2m27s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m22s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m26s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m9s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m19s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m19s
CI / changes (push) Successful in 7s
CI / openapi (push) Successful in 23s
CI / go (push) Successful in 24s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m7s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m2s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 55s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 54s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 2m19s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 2m27s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m22s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m26s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m9s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m19s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m19s
This commit is contained in:
+4
-5
@@ -704,8 +704,8 @@ components:
|
||||
KV настройки tenant/глобальные лимиты и feature flags.
|
||||
Параметры BIRD (строки в `global_settings`, JSON-значения — обычно строка или число):
|
||||
`bird_router_id`, `bird_local_ipv4`, `bird_local_ipv6`, `bird_local_asn`;
|
||||
`bird_bgp_source_ipv4` / `bird_bgp_source_ipv6` — для `source address` у BGP-пиров (если не заданы — эффективный `bird_local_ipv4` / политика пира).
|
||||
Если задан `bird_bgp_source_ipv4`, он же подставляется как BIRD `router id` (перекрывает `bird_router_id`).
|
||||
если задан `bird_bgp_source_ipv4`, он подставляется как BIRD `router id` (перекрывает `bird_router_id`).
|
||||
Ключи `bird_bgp_source_ipv4` / `bird_bgp_source_ipv6` в сгенерированном BGP для пиров не используются (оставлены для совместимости API).
|
||||
Шаблон BGP в конфиге: `local as <bird_local_asn>;` без локального IP.
|
||||
properties:
|
||||
bird_router_id:
|
||||
@@ -720,11 +720,10 @@ components:
|
||||
bird_bgp_source_ipv4:
|
||||
type: string
|
||||
description: |
|
||||
Исходящий IPv4 для `source address` у пиров; также задаёт `router id`, если указан.
|
||||
На стороне MikroTik в BGP Connection поле **Remote address** должно совпадать с этим адресом (или с тем, с которого реально устанавливается TCP-сессия к 179/tcp), иначе сессия не поднимется.
|
||||
Если задан — используется как BIRD `router id` (IPv4). В блоках `protocol bgp … from bgp_template` строка `source address` не генерируется.
|
||||
bird_bgp_source_ipv6:
|
||||
type: string
|
||||
description: Исходящий IPv6 для `source address` у пиров IPv6.
|
||||
description: Зарезервировано; в текущей генерации BGP не используется.
|
||||
additionalProperties: true
|
||||
|
||||
RevisionDiff:
|
||||
|
||||
+4
-13
@@ -12,7 +12,7 @@ const (
|
||||
)
|
||||
|
||||
// BGPTemplatesOptions holds ASN and export filters for template bgp bgp_template (+ v6 mirror).
|
||||
// Templates use "local as <asn>;" only (no local IP); peers supply source address / optional local override.
|
||||
// Templates use "local as <asn>;" only (no local IP); peers add neighbor / multihop / passive and optional "local … as …" override.
|
||||
type BGPTemplatesOptions struct {
|
||||
LocalASN uint32
|
||||
ExportFilterV4 string
|
||||
@@ -43,8 +43,6 @@ func RenderBGPTemplates(opts BGPTemplatesOptions) (string, error) {
|
||||
b.WriteString(" };\n")
|
||||
b.WriteString(" hold time 90;\n")
|
||||
b.WriteString(" keepalive time 30;\n")
|
||||
// Жёсткая привязка к source address (см. пир): полезно в Docker / bridge, иначе listen может уйти на 0.0.0.0.
|
||||
b.WriteString(" strict bind on;\n")
|
||||
b.WriteString("}\n\n")
|
||||
fmt.Fprintf(&b, "template bgp %s {\n", BGPTemplateNameV6)
|
||||
fmt.Fprintf(&b, " local as %d;\n", opts.LocalASN)
|
||||
@@ -56,7 +54,6 @@ func RenderBGPTemplates(opts BGPTemplatesOptions) (string, error) {
|
||||
b.WriteString(" };\n")
|
||||
b.WriteString(" hold time 90;\n")
|
||||
b.WriteString(" keepalive time 30;\n")
|
||||
b.WriteString(" strict bind on;\n")
|
||||
b.WriteString("}\n")
|
||||
return b.String(), nil
|
||||
}
|
||||
@@ -67,14 +64,12 @@ type BGPPeerFromTemplateOptions struct {
|
||||
TemplateName string
|
||||
NeighborIP string
|
||||
NeighborASN uint32
|
||||
SourceAddress string
|
||||
// If set, emits "local … as …" before neighbor (overrides template local/ASN for this peer).
|
||||
OverrideLocalIP string
|
||||
OverrideLocalASN uint32
|
||||
}
|
||||
|
||||
// RenderProtocolBGPFromTemplate renders protocol bgp … from TEMPLATE { neighbor; multihop; source address; strict bind; passive; }.
|
||||
// strict bind дублируется и в шаблоне, и в каждом пире — явная фиксация на сессию.
|
||||
// RenderProtocolBGPFromTemplate renders protocol bgp … from TEMPLATE { neighbor; multihop; passive; }.
|
||||
func RenderProtocolBGPFromTemplate(opts BGPPeerFromTemplateOptions) (string, error) {
|
||||
if strings.TrimSpace(opts.ProtocolName) == "" {
|
||||
return "", fmt.Errorf("birdfmt: protocol name is required")
|
||||
@@ -82,8 +77,8 @@ func RenderProtocolBGPFromTemplate(opts BGPPeerFromTemplateOptions) (string, err
|
||||
if strings.TrimSpace(opts.TemplateName) == "" {
|
||||
return "", fmt.Errorf("birdfmt: template name is required")
|
||||
}
|
||||
if strings.TrimSpace(opts.NeighborIP) == "" || strings.TrimSpace(opts.SourceAddress) == "" {
|
||||
return "", fmt.Errorf("birdfmt: neighbor and source address are required")
|
||||
if strings.TrimSpace(opts.NeighborIP) == "" {
|
||||
return "", fmt.Errorf("birdfmt: neighbor is required")
|
||||
}
|
||||
if opts.NeighborASN == 0 {
|
||||
return "", fmt.Errorf("birdfmt: neighbor ASN must be non-zero")
|
||||
@@ -107,10 +102,6 @@ func RenderProtocolBGPFromTemplate(opts BGPPeerFromTemplateOptions) (string, err
|
||||
b.WriteString(strings.TrimSpace(opts.NeighborIP))
|
||||
fmt.Fprintf(&b, " as %d;\n", opts.NeighborASN)
|
||||
b.WriteString(" multihop;\n")
|
||||
b.WriteString(" source address ")
|
||||
b.WriteString(strings.TrimSpace(opts.SourceAddress))
|
||||
b.WriteString(";\n")
|
||||
b.WriteString(" strict bind on;\n")
|
||||
b.WriteString(" passive;\n")
|
||||
b.WriteString("}\n")
|
||||
return b.String(), nil
|
||||
|
||||
@@ -37,11 +37,10 @@ func TestRenderBGPTemplates_Validation(t *testing.T) {
|
||||
|
||||
func TestRenderProtocolBGPFromTemplate_MultihopPassive(t *testing.T) {
|
||||
got, err := RenderProtocolBGPFromTemplate(BGPPeerFromTemplateOptions{
|
||||
ProtocolName: "evobgp_p_x",
|
||||
TemplateName: BGPTemplateNameV4,
|
||||
NeighborIP: "94.142.140.141",
|
||||
NeighborASN: 65002,
|
||||
SourceAddress: "77.232.38.173",
|
||||
ProtocolName: "evobgp_p_x",
|
||||
TemplateName: BGPTemplateNameV4,
|
||||
NeighborIP: "94.142.140.141",
|
||||
NeighborASN: 65002,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -52,10 +51,7 @@ func TestRenderProtocolBGPFromTemplate_MultihopPassive(t *testing.T) {
|
||||
if !strings.Contains(got, "multihop;") || !strings.Contains(got, "passive;") {
|
||||
t.Fatal(got)
|
||||
}
|
||||
if !strings.Contains(got, "source address 77.232.38.173;") {
|
||||
t.Fatal(got)
|
||||
}
|
||||
if !strings.Contains(got, "strict bind on;") {
|
||||
if strings.Contains(got, "source address") || strings.Contains(got, "strict bind") {
|
||||
t.Fatal(got)
|
||||
}
|
||||
}
|
||||
@@ -66,7 +62,6 @@ func TestRenderProtocolBGPFromTemplate_OverrideLocal(t *testing.T) {
|
||||
TemplateName: BGPTemplateNameV4,
|
||||
NeighborIP: "192.0.2.2",
|
||||
NeighborASN: 2,
|
||||
SourceAddress: "10.0.0.1",
|
||||
OverrideLocalIP: "10.0.0.1",
|
||||
OverrideLocalASN: 65099,
|
||||
})
|
||||
|
||||
@@ -40,11 +40,10 @@ func TestStandardLayout_GeneratorMatchesFixtures(t *testing.T) {
|
||||
assertFileEquals(t, "testdata/scenarios/standard_layout/bird.d/evobgp_bgp_template.conf", tpl)
|
||||
|
||||
peer, err := RenderProtocolBGPFromTemplate(BGPPeerFromTemplateOptions{
|
||||
ProtocolName: "evobgp_peer_ci",
|
||||
TemplateName: BGPTemplateNameV4,
|
||||
NeighborIP: "192.0.2.2",
|
||||
NeighborASN: 65002,
|
||||
SourceAddress: "192.0.2.1",
|
||||
ProtocolName: "evobgp_peer_ci",
|
||||
TemplateName: BGPTemplateNameV4,
|
||||
NeighborIP: "192.0.2.2",
|
||||
NeighborASN: 65002,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
-2
@@ -6,7 +6,6 @@ template bgp bgp_template {
|
||||
};
|
||||
hold time 90;
|
||||
keepalive time 30;
|
||||
strict bind on;
|
||||
}
|
||||
|
||||
template bgp bgp_template_v6 {
|
||||
@@ -17,5 +16,4 @@ template bgp bgp_template_v6 {
|
||||
};
|
||||
hold time 90;
|
||||
keepalive time 30;
|
||||
strict bind on;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
protocol bgp evobgp_peer_ci from bgp_template {
|
||||
neighbor 192.0.2.2 as 65002;
|
||||
multihop;
|
||||
source address 192.0.2.1;
|
||||
strict bind on;
|
||||
passive;
|
||||
}
|
||||
|
||||
@@ -331,9 +331,6 @@ type birdLocals struct {
|
||||
localV4 string
|
||||
localV6 string
|
||||
localASN uint32
|
||||
// Optional BGP TCP source (BIRD "source address"); empty => use effective local per peer.
|
||||
sourceV4 string
|
||||
sourceV6 string
|
||||
}
|
||||
|
||||
func birdLocalsFromStore(st store.Backend, tenantID string) birdLocals {
|
||||
@@ -361,30 +358,12 @@ func birdLocalsFromStore(st store.Backend, tenantID string) birdLocals {
|
||||
loc.localASN = n
|
||||
}
|
||||
if s := stringFromSettingsMap(settings, "bird_bgp_source_ipv4"); s != "" {
|
||||
loc.sourceV4 = s
|
||||
// BIRD router id must be an IPv4 address; align with BGP source when operator sets it.
|
||||
// BIRD router id must be an IPv4 address; historically aligned with optional BGP source setting.
|
||||
loc.routerID = strings.TrimSpace(s)
|
||||
}
|
||||
if s := stringFromSettingsMap(settings, "bird_bgp_source_ipv6"); s != "" {
|
||||
loc.sourceV6 = s
|
||||
}
|
||||
return loc
|
||||
}
|
||||
|
||||
func bgpPeerSourceIPv4(loc birdLocals, effectiveLocal string) string {
|
||||
if s := strings.TrimSpace(loc.sourceV4); s != "" {
|
||||
return s
|
||||
}
|
||||
return effectiveLocal
|
||||
}
|
||||
|
||||
func bgpPeerSourceIPv6(loc birdLocals, effectiveLocal string) string {
|
||||
if s := strings.TrimSpace(loc.sourceV6); s != "" {
|
||||
return s
|
||||
}
|
||||
return effectiveLocal
|
||||
}
|
||||
|
||||
func stringFromSettingsMap(m map[string]any, key string) string {
|
||||
v, ok := m[key]
|
||||
if !ok || v == nil {
|
||||
@@ -474,11 +453,10 @@ func renderPeersBirdFragment(st store.Backend, tenantID string, loc birdLocals)
|
||||
ra := uint32(p.RemoteASN)
|
||||
if addr.Is4() {
|
||||
opts := birdfmt.BGPPeerFromTemplateOptions{
|
||||
ProtocolName: proto,
|
||||
TemplateName: birdfmt.BGPTemplateNameV4,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
SourceAddress: bgpPeerSourceIPv4(loc, lv4),
|
||||
ProtocolName: proto,
|
||||
TemplateName: birdfmt.BGPTemplateNameV4,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
}
|
||||
if peerNeedsLocalOverride(loc, lv4, asn, true) {
|
||||
opts.OverrideLocalIP = lv4
|
||||
@@ -493,11 +471,10 @@ func renderPeersBirdFragment(st store.Backend, tenantID string, loc birdLocals)
|
||||
}
|
||||
if addr.Is6() {
|
||||
opts := birdfmt.BGPPeerFromTemplateOptions{
|
||||
ProtocolName: proto,
|
||||
TemplateName: birdfmt.BGPTemplateNameV6,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
SourceAddress: bgpPeerSourceIPv6(loc, lv6),
|
||||
ProtocolName: proto,
|
||||
TemplateName: birdfmt.BGPTemplateNameV6,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
}
|
||||
if peerNeedsLocalOverride(loc, lv6, asn, false) {
|
||||
opts.OverrideLocalIP = lv6
|
||||
|
||||
@@ -98,8 +98,8 @@
|
||||
<code class="text-xs">GET/PATCH /v1/settings</code> — глобальные параметры control plane (хранятся в БД).
|
||||
Требуется роль operator. Для BIRD, например:
|
||||
<code class="bg-muted rounded px-1 py-0.5 text-xs">bird_local_ipv4</code>,
|
||||
<code class="bg-muted rounded px-1 py-0.5 text-xs">bird_bgp_source_ipv4</code> (опционально — только для строки
|
||||
<code class="text-xs">source address</code> у BGP-пиров).
|
||||
<code class="bg-muted rounded px-1 py-0.5 text-xs">bird_bgp_source_ipv4</code> (опционально — задаёт BIRD
|
||||
<code class="text-xs">router id</code>).
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
@@ -111,7 +111,7 @@
|
||||
<p class="text-muted-foreground text-xs leading-relaxed">
|
||||
Должен быть строго валидный JSON: ключи и строки в двойных кавычках, без точки с запятой. Пример:
|
||||
<code class="bg-muted mt-1 block rounded px-2 py-1 font-mono"
|
||||
>{`{"bird_bgp_source_ipv4": "178.250.186.111"}`}</code
|
||||
>{`{"bird_router_id": "203.0.113.1", "bird_local_asn": 65001}`}</code
|
||||
>
|
||||
</p>
|
||||
<Textarea
|
||||
|
||||
Reference in New Issue
Block a user