Files
openlan/pkg/switch/bgp_linux.go
Daniel Ding 8457ef8162
Some checks failed
Coverage CI / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
Ubuntu CI / build (push) Has been cancelled
fix: reload frr failed.
2025-09-02 16:08:29 +08:00

166 lines
3.2 KiB
Go

package cswitch
import (
"os/exec"
"text/template"
"github.com/luscis/openlan/pkg/api"
co "github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/schema"
)
const (
BgpBin = "/var/openlan/script/frr-reload"
BgpEtc = "/etc/frr/frr.conf"
)
type BgpWorker struct {
*WorkerImpl
spec *co.BgpSpecifies
}
func NewBgpWorker(c *co.Network) *BgpWorker {
w := &BgpWorker{
WorkerImpl: NewWorkerApi(c),
}
w.spec, _ = c.Specifies.(*co.BgpSpecifies)
return w
}
var BgpTmpl = `! GENERATE BY OPENALN
!
service integrated-vtysh-config
{{- if .RouterId }}
router bgp {{ .LocalAs }}
bgp router-id {{ .RouterId }}
no bgp default ipv4-unicast
{{- range .Neighbors }}
neighbor {{ .Address }} remote-as {{ .RemoteAs }}
{{- end }}
!
address-family ipv4 unicast
redistribute connected
redistribute kernel
{{- range .Neighbors }}
neighbor {{ .Address }} activate
neighbor {{ .Address }} route-map {{ .Address }}-in in
neighbor {{ .Address }} route-map {{ .Address }}-out out
{{- end }}
exit-address-family
!
{{- range .Neighbors }}
ip prefix-list {{ .Address }}-out seq 10 permit any
ip prefix-list {{ .Address }}-in seq 10 permit any
{{- end }}
{{- range .Neighbors }}
route-map {{ .Address }}-in permit 10
match ip address prefix-list {{ .Address }}-in
!
{{- end }}
{{- range .Neighbors }}
route-map {{ .Address }}-out permit 10
match ip address prefix-list {{ .Address }}-out
!
{{- end }}
{{- end }}
!
`
func (w *BgpWorker) Initialize() {
w.out.Info("BgpWorker.Initialize")
}
func (w *BgpWorker) save() {
file := BgpEtc
out, err := libol.CreateFile(file)
if err != nil || out == nil {
return
}
defer out.Close()
if obj, err := template.New("main").Parse(BgpTmpl); err != nil {
w.out.Warn("BgpWorker.save: %s", err)
} else {
if err := obj.Execute(out, w.spec); err != nil {
w.out.Warn("BgpWorker.save: %s", err)
}
}
}
func (w *BgpWorker) reload() {
w.save()
cmd := exec.Command(BgpBin)
if err := cmd.Run(); err != nil {
w.out.Warn("BgpWorker.reload: %s", err)
return
}
}
func (w *BgpWorker) Start(v api.Switcher) {
w.uuid = v.UUID()
w.out.Info("BgpWorker.Start")
w.reload()
}
func (w *BgpWorker) Stop() {
w.out.Info("BgpWorker.Stop")
}
func (w *BgpWorker) Enable(data schema.Bgp) {
w.spec.LocalAs = data.LocalAs
w.spec.RouterId = data.RouterId
w.reload()
}
func (w *BgpWorker) Disable() {
w.spec.RouterId = ""
w.spec.LocalAs = 0
w.reload()
}
func (w *BgpWorker) Get() *schema.Bgp {
data := &schema.Bgp{
LocalAs: w.spec.LocalAs,
RouterId: w.spec.RouterId,
}
for _, nei := range w.spec.Neighbors {
obj := schema.BgpNeighbor{
Address: nei.Address,
RemoteAs: nei.RemoteAs,
}
data.Neighbors = append(data.Neighbors, obj)
}
return data
}
func (w *BgpWorker) Reload(v api.Switcher) {
w.Stop()
w.Initialize()
w.Start(v)
}
func (w *BgpWorker) AddNeighbor(data schema.BgpNeighbor) {
cfg := &co.BgpNeighbor{
Address: data.Address,
RemoteAs: data.RemoteAs,
}
cfg.Correct()
if w.spec.AddNeighbor(cfg) {
w.reload()
}
}
func (w *BgpWorker) DelNeighbor(data schema.BgpNeighbor) {
cfg := &co.BgpNeighbor{
Address: data.Address,
RemoteAs: data.RemoteAs,
}
cfg.Correct()
if _, removed := w.spec.DelNeighbor(cfg); removed {
w.reload()
}
}