mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-10-09 00:41:05 +02:00
142 lines
3.3 KiB
Go
Executable File
142 lines
3.3 KiB
Go
Executable File
// +build linux
|
|
|
|
package nlgo
|
|
|
|
import (
|
|
"log"
|
|
"net"
|
|
"syscall"
|
|
"testing"
|
|
"unsafe"
|
|
)
|
|
|
|
// This basic rtnetlink example lists up link interfaces.
|
|
func Example() {
|
|
sock := NlSocketAlloc()
|
|
defer NlSocketFree(sock)
|
|
if err := NlConnect(sock, syscall.NETLINK_ROUTE); err != nil {
|
|
panic(err)
|
|
}
|
|
req := make([]byte, NLMSG_ALIGN(syscall.SizeofIfInfomsg))
|
|
if err := NlSendSimple(sock, syscall.RTM_GETLINK, syscall.NLM_F_DUMP, req); err != nil {
|
|
panic(err)
|
|
}
|
|
func() {
|
|
for {
|
|
buf := make([]byte, syscall.Getpagesize())
|
|
if nn, _, err := syscall.Recvfrom(sock.Fd, buf, syscall.MSG_TRUNC); err != nil {
|
|
panic(err)
|
|
} else if nn > len(buf) {
|
|
panic("out of recv buf")
|
|
} else {
|
|
buf = buf[:nn]
|
|
}
|
|
if msgs, err := syscall.ParseNetlinkMessage(buf); err != nil {
|
|
panic(err)
|
|
} else {
|
|
for _, msg := range msgs {
|
|
switch msg.Header.Type {
|
|
case syscall.RTM_NEWLINK:
|
|
ifinfo := (*syscall.IfInfomsg)(unsafe.Pointer(&msg.Data[0]))
|
|
if attrs, err := RouteLinkPolicy.Parse(msg.Data[NLA_ALIGN(syscall.SizeofIfInfomsg):]); err != nil {
|
|
panic(err)
|
|
} else {
|
|
log.Print("ifinfomsg=", ifinfo, " attrs=", attrs)
|
|
}
|
|
case syscall.NLMSG_DONE:
|
|
return
|
|
default:
|
|
log.Print("unhandled msg", msg.Header)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
// This is RTNLGRP_LINK listener example. RTNLGRP_LINK is newer version of RTMGRP_LINK.
|
|
func ExampleNlSocketAddMembership() {
|
|
sock := NlSocketAlloc()
|
|
defer NlSocketFree(sock)
|
|
if err := NlConnect(sock, syscall.NETLINK_ROUTE); err != nil {
|
|
panic(err)
|
|
}
|
|
if err := NlSocketAddMembership(sock, syscall.RTNLGRP_LINK); err != nil {
|
|
panic(err)
|
|
}
|
|
for {
|
|
buf := make([]byte, syscall.Getpagesize())
|
|
if nn, _, err := syscall.Recvfrom(sock.Fd, buf, syscall.MSG_TRUNC); err != nil {
|
|
panic(err)
|
|
} else if nn > len(buf) {
|
|
panic("out of recv buf")
|
|
} else {
|
|
buf = buf[:nn]
|
|
}
|
|
if msgs, err := syscall.ParseNetlinkMessage(buf); err != nil {
|
|
panic(err)
|
|
} else {
|
|
for _, msg := range msgs {
|
|
switch msg.Header.Type {
|
|
case syscall.RTM_NEWLINK, syscall.RTM_DELLINK, syscall.RTM_GETLINK:
|
|
ifinfo := (*syscall.IfInfomsg)(unsafe.Pointer(&msg.Data[0]))
|
|
if attrs, err := RouteLinkPolicy.Parse(msg.Data[NLA_ALIGN(syscall.SizeofIfInfomsg):]); err != nil {
|
|
panic(err)
|
|
} else {
|
|
log.Print("ifinfomsg=", ifinfo, " attrs=", attrs)
|
|
}
|
|
default:
|
|
log.Print("unhandled msg")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRoute(t *testing.T) {
|
|
if hub, err := NewRtHub(); err != nil {
|
|
panic(err)
|
|
} else {
|
|
defer hub.Close()
|
|
|
|
req := syscall.NetlinkMessage{
|
|
Header: syscall.NlMsghdr{
|
|
Type: syscall.RTM_GETROUTE,
|
|
Flags: syscall.NLM_F_REQUEST,
|
|
},
|
|
}
|
|
(*RtMessage)(&req).Set(
|
|
syscall.RtMsg{
|
|
Family: syscall.AF_INET6,
|
|
},
|
|
AttrSlice{
|
|
Attr{
|
|
Header: syscall.NlAttr{
|
|
Type: syscall.RTA_DST,
|
|
},
|
|
Value: Binary(net.ParseIP("2001:503:ba3e::2:30").To16()),
|
|
},
|
|
},
|
|
)
|
|
if msgs, err := hub.Sync(req); err != nil {
|
|
panic(err)
|
|
} else {
|
|
for _, msg := range msgs {
|
|
switch msg.Header.Type {
|
|
case syscall.NLMSG_ERROR:
|
|
err := NlMsgerr(msg)
|
|
if err.Payload().Error != 0 {
|
|
t.Error(err)
|
|
}
|
|
case syscall.RTM_NEWROUTE:
|
|
if attr, err := RtMessage(msg).Attrs(); err != nil {
|
|
t.Error(err)
|
|
} else {
|
|
t.Log(attr)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|