fea: state for bgp neighbor.
Some checks failed
Coverage CI / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
Ubuntu CI / build (push) Has been cancelled

This commit is contained in:
Daniel Ding
2025-09-04 16:39:49 +08:00
parent 101e1e37a3
commit db26f4881f
4 changed files with 93 additions and 29 deletions

51
dist/rootfs/var/openlan/script/frr-client vendored Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python3
import argparse
import socket
import sys
SOCKET_PATH = "/var/openlan/frr/reloader.sock"
def receive_message(conn, buffer_size=1024):
data = []
while True:
chunk = conn.recv(buffer_size)
if not chunk:
break
data.append(chunk)
return b''.join(data).decode('utf-8')
def client(action):
code = 0
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
client.connect(SOCKET_PATH)
client.send(action.encode('utf-8'))
response = receive_message(client)
print(f"{response}")
if action == "reload" and response != "success":
code = 1
return
except Exception as e:
print(f"Error: {e}")
code = 2
finally:
client.close()
return code
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--reload', action='store_true', help='reload frr')
parser.add_argument('--show-neighbors', action='store_true', help='show bgp neighbor')
args = parser.parse_args()
code = 0
if args.reload:
code = client("reload")
elif args.show_neighbors:
code = client("show-neighbors")
sys.exit(code)

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env python3
import socket
import sys
import logging
SOCKET_PATH = "/var/openlan/frr/reloader.sock"
def client():
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
client.connect(SOCKET_PATH)
message = "reload"
client.send(message.encode('utf-8'))
response = client.recv(1024).decode('utf-8')
print(f"{response}")
if response != "success":
sys,exit(1)
except Exception as e:
print(f"Error: {e}")
finally:
client.close()
if __name__ == "__main__":
client()

View File

@@ -3,6 +3,8 @@
import socket import socket
import os import os
import logging import logging
import subprocess
import json
SOCKET_PATH = "/var/openlan/frr/reloader.sock" SOCKET_PATH = "/var/openlan/frr/reloader.sock"
@@ -13,12 +15,31 @@ logging.basicConfig(
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def do_vtyshell(command):
proc = subprocess.Popen(['vtysh', '-c', command], stdout=subprocess.PIPE, text=True)
stdout, stderr = proc.communicate()
if proc.returncode == 0:
return True, stdout
return False, stderr
def handle_reload(): def handle_reload():
code = os.system("/usr/lib/frr/frr-reload") code = os.system("/usr/lib/frr/frr-reload")
if code == 0: if code == 0:
return "success" return "success"
return "fail" return "fail"
def handle_show_neighbors():
ok, data = do_vtyshell('show bgp neighbor json')
if not ok:
return ""
neighbors = json.loads(data)
status = {}
for addr, nei in neighbors.items():
status[addr] = {"state": nei.get('bgpState')}
return json.dumps(status)
def handle_client(server): def handle_client(server):
try: try:
client, _ = server.accept() client, _ = server.accept()
@@ -30,6 +51,8 @@ def handle_client(server):
response = "unsupport" response = "unsupport"
if message == "reload": if message == "reload":
response = handle_reload() response = handle_reload()
elif message == "show-neighbors":
response = handle_show_neighbors()
client.send(response.encode('utf-8')) client.send(response.encode('utf-8'))
logger.debug(f"Sent response: {response}") logger.debug(f"Sent response: {response}")

View File

@@ -2,6 +2,7 @@ package cswitch
import ( import (
"os/exec" "os/exec"
"strings"
"text/template" "text/template"
"github.com/luscis/openlan/pkg/api" "github.com/luscis/openlan/pkg/api"
@@ -11,7 +12,7 @@ import (
) )
const ( const (
BgpBin = "/var/openlan/script/frr-reload" BgpBin = "/var/openlan/script/frr-client"
BgpEtc = "/etc/frr/frr.conf" BgpEtc = "/etc/frr/frr.conf"
) )
@@ -108,7 +109,7 @@ func (w *BgpWorker) save() {
func (w *BgpWorker) reload() { func (w *BgpWorker) reload() {
w.save() w.save()
cmd := exec.Command(BgpBin) cmd := exec.Command(BgpBin, "--reload")
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
w.out.Warn("BgpWorker.reload: %s", err) w.out.Warn("BgpWorker.reload: %s", err)
return return
@@ -142,6 +143,19 @@ func (w *BgpWorker) Get() *schema.Bgp {
LocalAs: w.spec.LocalAs, LocalAs: w.spec.LocalAs,
RouterId: w.spec.RouterId, RouterId: w.spec.RouterId,
} }
show := map[string]struct {
State string `json:"state"`
}{}
out, err := exec.Command(BgpBin, "--show-neighbors").CombinedOutput()
if err == nil {
if err := libol.Unmarshal(&show, out); err != nil {
w.out.Warn("BgpWorker.Get.Status: %s", err)
}
} else {
w.out.Warn("BgpWorker.Get.Status: %s", err)
}
for _, nei := range w.spec.Neighbors { for _, nei := range w.spec.Neighbors {
obj := schema.BgpNeighbor{ obj := schema.BgpNeighbor{
Address: nei.Address, Address: nei.Address,
@@ -150,6 +164,9 @@ func (w *BgpWorker) Get() *schema.Bgp {
Receives: nei.Receives, Receives: nei.Receives,
Advertis: nei.Advertis, Advertis: nei.Advertis,
} }
if state, ok := show[nei.Address]; ok {
obj.State = strings.ToLower(state.State)
}
data.Neighbors = append(data.Neighbors, obj) data.Neighbors = append(data.Neighbors, obj)
} }
return data return data