fea: show kernel neighbors.
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-11-26 15:02:51 +08:00
parent a33fcff822
commit da0d6d853d
6 changed files with 126 additions and 30 deletions

View File

@@ -19,23 +19,46 @@ func (l KernelRoute) Router(router *mux.Router) {
}
func (l KernelRoute) List(w http.ResponseWriter, r *http.Request) {
var items []schema.PrefixRoute
var items []schema.KernelRoute
routes, _ := libol.ListRoutes()
for _, prefix := range routes {
item := schema.PrefixRoute{
Link: prefix.Link,
Metric: prefix.Priority,
Table: prefix.Table,
Source: prefix.Src,
NextHop: prefix.Gw,
Prefix: prefix.Dst,
Protocol: prefix.Protocol,
values, _ := libol.ListRoutes()
for _, val := range values {
item := schema.KernelRoute{
Link: val.Link,
Metric: val.Priority,
Table: val.Table,
Source: val.Src,
NextHop: val.Gw,
Prefix: val.Dst,
Protocol: val.Protocol,
}
items = append(items, item)
}
ResponseJson(w, items)
}
type KernelNeighbor struct {
}
func (l KernelNeighbor) Router(router *mux.Router) {
router.HandleFunc("/api/kernel/neighbor", l.List).Methods("GET")
}
func (l KernelNeighbor) List(w http.ResponseWriter, r *http.Request) {
var items []schema.KernelNeighbor
values, _ := libol.ListNeighbrs()
for _, val := range values {
item := schema.KernelNeighbor{
Link: val.Link,
Address: val.Address,
HwAddr: val.HwAddr,
State: val.State,
}
items = append(items, item)
}
ResponseJson(w, items)
}

View File

@@ -6,6 +6,7 @@ func Add(router *mux.Router, cs SwitchApi) {
Link{cs: cs}.Router(router)
User{}.Router(router)
KernelRoute{}.Router(router)
KernelNeighbor{}.Router(router)
Neighbor{}.Router(router)
Access{}.Router(router)
OnLine{}.Router(router)

View File

@@ -85,40 +85,84 @@ func RouteProtocol(code int) string {
}
func ListRoutes() ([]Prefix, error) {
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
var items []Prefix
values, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
var data []Prefix
for _, rte := range routes {
for _, value := range values {
entry := Prefix{
Protocol: RouteProtocol(rte.Protocol),
Priority: rte.Priority,
Protocol: RouteProtocol(value.Protocol),
Priority: value.Priority,
}
link, err := netlink.LinkByIndex(rte.LinkIndex)
link, err := netlink.LinkByIndex(value.LinkIndex)
if err == nil {
entry.Link = link.Attrs().Name
}
if rte.Dst == nil {
if value.Dst == nil {
entry.Dst = "0.0.0.0/0"
} else {
entry.Dst = rte.Dst.String()
entry.Dst = value.Dst.String()
}
if len(rte.Gw) == 0 {
if len(value.Gw) == 0 {
entry.Gw = "0.0.0.0"
} else {
entry.Gw = rte.Gw.String()
entry.Gw = value.Gw.String()
}
if len(rte.Src) == 0 {
if len(value.Src) == 0 {
entry.Src = "0.0.0.0"
} else {
entry.Src = rte.Src.String()
entry.Src = value.Src.String()
}
data = append(data, entry)
items = append(items, entry)
}
return data, nil
return items, nil
}
func StateCode(code int) string {
switch code {
case 0x00:
return "NONE"
case 0x01:
return "INCOMPLETE"
case 0x02:
return "REACHABLE"
case 0x04:
return "STALE"
case 0x08:
return "DELAY"
case 0x10:
return "PROBE"
case 0x20:
return "FAILED"
case 0x40:
return "NOARP"
case 0x80:
return "PERMANENT"
default:
return fmt.Sprintf("%d", code)
}
}
func ListNeighbrs() ([]Neighbor, error) {
var items []Neighbor
values, err := netlink.NeighList(0, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
for _, value := range values {
entry := Neighbor{
Address: value.IP.String(),
HwAddr: value.HardwareAddr.String(),
State: StateCode(value.State),
}
link, err := netlink.LinkByIndex(value.LinkIndex)
if err == nil {
entry.Link = link.Attrs().Name
}
items = append(items, entry)
}
return items, nil
}

View File

@@ -10,5 +10,9 @@ func GetLocalByGw(addr string) (net.IP, error) {
}
func ListRoutes() ([]Prefix, error) {
return nil, NewErr("ListRoute notSupport")
return nil, NewErr("ListRoutes notSupport")
}
func ListNeighbrs() ([]Neighbor, error) {
return nil, NewErr("ListNeighbors notSupport")
}

View File

@@ -9,3 +9,10 @@ type Prefix struct {
Priority int
Table int
}
type Neighbor struct {
Link string
Address string
HwAddr string
State string
}

View File

@@ -20,6 +20,23 @@ type PrefixRoute struct {
MultiPath []MultiPath `json:"multipath,omitempty"`
}
type KernelRoute struct {
Prefix string `json:"prefix"`
NextHop string `json:"nexthop,omitempty"`
Metric int `json:"metric"`
Link string `json:"link,omitempty"`
Table int `json:"table,omitempty"`
Source string `json:"source,omitempty"`
Protocol string `json:"protocol,omitempty"`
}
type KernelNeighbor struct {
Link string `json:"link,omitempty"`
Address string `json:"address,omitempty"`
HwAddr string `json:"hwaddr,omitempty"`
State string `json:"state,omitempty"`
}
type MultiPath struct {
NextHop string `json:"nexthop"`
Weight int `json:"weight"`