github.com/sagernet/netlink@v0.0.0-20240612041022-b9a21c07ac6a/nl/route_linux.go (about)

     1  package nl
     2  
     3  import (
     4  	"unsafe"
     5  
     6  	"golang.org/x/sys/unix"
     7  )
     8  
     9  type RtMsg struct {
    10  	unix.RtMsg
    11  }
    12  
    13  func NewRtMsg() *RtMsg {
    14  	return &RtMsg{
    15  		RtMsg: unix.RtMsg{
    16  			Table:    unix.RT_TABLE_MAIN,
    17  			Scope:    unix.RT_SCOPE_UNIVERSE,
    18  			Protocol: unix.RTPROT_BOOT,
    19  			Type:     unix.RTN_UNICAST,
    20  		},
    21  	}
    22  }
    23  
    24  func NewRtDelMsg() *RtMsg {
    25  	return &RtMsg{
    26  		RtMsg: unix.RtMsg{
    27  			Table: unix.RT_TABLE_MAIN,
    28  			Scope: unix.RT_SCOPE_NOWHERE,
    29  		},
    30  	}
    31  }
    32  
    33  func (msg *RtMsg) Len() int {
    34  	return unix.SizeofRtMsg
    35  }
    36  
    37  func DeserializeRtMsg(b []byte) *RtMsg {
    38  	return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0]))
    39  }
    40  
    41  func (msg *RtMsg) Serialize() []byte {
    42  	return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
    43  }
    44  
    45  type RtNexthop struct {
    46  	unix.RtNexthop
    47  	Children []NetlinkRequestData
    48  }
    49  
    50  func DeserializeRtNexthop(b []byte) *RtNexthop {
    51  	return &RtNexthop{
    52  		RtNexthop: *((*unix.RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0]))),
    53  	}
    54  }
    55  
    56  func (msg *RtNexthop) Len() int {
    57  	if len(msg.Children) == 0 {
    58  		return unix.SizeofRtNexthop
    59  	}
    60  
    61  	l := 0
    62  	for _, child := range msg.Children {
    63  		l += rtaAlignOf(child.Len())
    64  	}
    65  	l += unix.SizeofRtNexthop
    66  	return rtaAlignOf(l)
    67  }
    68  
    69  func (msg *RtNexthop) Serialize() []byte {
    70  	length := msg.Len()
    71  	msg.RtNexthop.Len = uint16(length)
    72  	buf := make([]byte, length)
    73  	copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
    74  	next := rtaAlignOf(unix.SizeofRtNexthop)
    75  	if len(msg.Children) > 0 {
    76  		for _, child := range msg.Children {
    77  			childBuf := child.Serialize()
    78  			copy(buf[next:], childBuf)
    79  			next += rtaAlignOf(len(childBuf))
    80  		}
    81  	}
    82  	return buf
    83  }
    84  
    85  type RtGenMsg struct {
    86  	unix.RtGenmsg
    87  }
    88  
    89  func NewRtGenMsg() *RtGenMsg {
    90  	return &RtGenMsg{
    91  		RtGenmsg: unix.RtGenmsg{
    92  			Family: unix.AF_UNSPEC,
    93  		},
    94  	}
    95  }
    96  
    97  func (msg *RtGenMsg) Len() int {
    98  	return rtaAlignOf(unix.SizeofRtGenmsg)
    99  }
   100  
   101  func DeserializeRtGenMsg(b []byte) *RtGenMsg {
   102  	return &RtGenMsg{RtGenmsg: unix.RtGenmsg{Family: b[0]}}
   103  }
   104  
   105  func (msg *RtGenMsg) Serialize() []byte {
   106  	out := make([]byte, msg.Len())
   107  	out[0] = msg.Family
   108  	return out
   109  }