mirror of
https://github.com/luscis/openlan.git
synced 2025-10-06 00:57:03 +08:00
166 lines
3.2 KiB
Go
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()
|
|
}
|
|
}
|