Skip to content

Instantly share code, notes, and snippets.

@vishvananda
Last active January 13, 2022 19:53
Show Gist options
  • Save vishvananda/ba20c1a97f3d06e9f0494c2f47d4c2ef to your computer and use it in GitHub Desktop.
Save vishvananda/ba20c1a97f3d06e9f0494c2f47d4c2ef to your computer and use it in GitHub Desktop.
diff --git a/nl/nl_linux.go b/nl/nl_linux.go
index ab76091..a49f675 100644
--- a/nl/nl_linux.go
+++ b/nl/nl_linux.go
@@ -27,7 +27,8 @@ const (
// tc rules or filters, or other more memory requiring data.
RECEIVE_BUFFER_SIZE = 65536
// Kernel netlink pid
- PidKernel uint32 = 0
+ PidKernel uint32 = 0
+ SizeofCnMsgOp = 0x18
)
// SupportedNlFamilies contains the list of netlink families this netlink package supports
@@ -106,7 +107,7 @@ type CnMsg struct {
type CnMsgOp struct {
CnMsg
// here we differ from the C header
- op uint32
+ Op uint32
}
func NewCnMsg(idx, val, op uint32) *CnMsgOp {
@@ -118,22 +119,21 @@ func NewCnMsg(idx, val, op uint32) *CnMsgOp {
cm.Ack = 0
cm.Seq = 1
cm.Length = uint16(binary.Size(op))
- cm.op = op
+ cm.Op = op
return &cm
}
func (msg *CnMsgOp) Serialize() []byte {
- buf := bytes.NewBuffer(make([]byte, 0, msg.Len()))
+ return (*(*[SizeofCnMsgOp]byte)(unsafe.Pointer(msg)))[:]
+}
- binary.Write(buf, binary.LittleEndian, msg)
- binary.Write(buf, binary.LittleEndian, msg.op)
-
- return buf.Bytes()
+func DeserializeCnMsgOp(b []byte) *CnMsgOp {
+ return (*CnMsgOp)(unsafe.Pointer(&b[0:SizeofCnMsgOp][0]))
}
func (msg *CnMsgOp) Len() int {
- return binary.Size(msg) + binary.Size(msg.op)
+ return SizeofCnMsgOp
}
// IfInfomsg is related to links, but it is used for list requests as well
diff --git a/nl/nl_linux_test.go b/nl/nl_linux_test.go
index 8971602..c6d294e 100644
--- a/nl/nl_linux_test.go
+++ b/nl/nl_linux_test.go
@@ -98,3 +98,36 @@ func TestIfSocketCloses(t *testing.T) {
t.Fatalf("Expected error instead received nil")
}
}
+
+func (msg *CnMsgOp) write(b []byte) {
+ native := NativeEndian()
+ native.PutUint32(b[0:4], msg.ID.Idx)
+ native.PutUint32(b[4:8], msg.ID.Val)
+ native.PutUint32(b[8:12], msg.Seq)
+ native.PutUint32(b[12:16], msg.Ack)
+ native.PutUint16(b[16:18], msg.Length)
+ native.PutUint16(b[18:20], msg.Flags)
+ native.PutUint32(b[20:24], msg.Op)
+}
+
+func (msg *CnMsgOp) serializeSafe() []byte {
+ length := msg.Len()
+ b := make([]byte, length)
+ msg.write(b)
+ return b
+}
+
+func deserializeCnMsgOpSafe(b []byte) *CnMsgOp {
+ var msg = CnMsgOp{}
+ binary.Read(bytes.NewReader(b[0:SizeofCnMsgOp]), NativeEndian(), &msg)
+ return &msg
+}
+
+func TestCnMsgOpDeserializeSerialize(t *testing.T) {
+ x := CnMsgOp{}
+ var orig = make([]byte, SizeofCnMsgOp)
+ rand.Read(orig)
+ safemsg := deserializeCnMsgOpSafe(orig)
+ msg := DeserializeCnMsgOp(orig)
+ testDeserializeSerialize(t, orig, safemsg, msg)
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment