mirror of
https://github.com/vishvananda/netlink.git
synced 2025-09-27 04:05:59 +08:00
Add XfrmAllocSpi
This commit is contained in:

committed by
Vish Ishaya

parent
9a7970b3b6
commit
3c27c1c1e3
@@ -8,6 +8,7 @@ const (
|
|||||||
SizeofXfrmUsersaId = 0x18
|
SizeofXfrmUsersaId = 0x18
|
||||||
SizeofXfrmStats = 0x0c
|
SizeofXfrmStats = 0x0c
|
||||||
SizeofXfrmUsersaInfo = 0xe0
|
SizeofXfrmUsersaInfo = 0xe0
|
||||||
|
SizeofXfrmUserSpiInfo = 0xe8
|
||||||
SizeofXfrmAlgo = 0x44
|
SizeofXfrmAlgo = 0x44
|
||||||
SizeofXfrmAlgoAuth = 0x48
|
SizeofXfrmAlgoAuth = 0x48
|
||||||
SizeofXfrmAlgoAEAD = 0x48
|
SizeofXfrmAlgoAEAD = 0x48
|
||||||
@@ -120,6 +121,30 @@ func (msg *XfrmUsersaInfo) Serialize() []byte {
|
|||||||
return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:]
|
return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct xfrm_userspi_info {
|
||||||
|
// struct xfrm_usersa_info info;
|
||||||
|
// __u32 min;
|
||||||
|
// __u32 max;
|
||||||
|
// };
|
||||||
|
|
||||||
|
type XfrmUserSpiInfo struct {
|
||||||
|
XfrmUsersaInfo XfrmUsersaInfo
|
||||||
|
Min uint32
|
||||||
|
Max uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *XfrmUserSpiInfo) Len() int {
|
||||||
|
return SizeofXfrmUserSpiInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeXfrmUserSpiInfo(b []byte) *XfrmUserSpiInfo {
|
||||||
|
return (*XfrmUserSpiInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserSpiInfo][0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *XfrmUserSpiInfo) Serialize() []byte {
|
||||||
|
return (*(*[SizeofXfrmUserSpiInfo]byte)(unsafe.Pointer(msg)))[:]
|
||||||
|
}
|
||||||
|
|
||||||
// struct xfrm_algo {
|
// struct xfrm_algo {
|
||||||
// char alg_name[64];
|
// char alg_name[64];
|
||||||
// unsigned int alg_key_len; /* in bits */
|
// unsigned int alg_key_len; /* in bits */
|
||||||
|
@@ -118,6 +118,33 @@ func (msg *XfrmAlgo) serializeSafe() []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (msg *XfrmUserSpiInfo) write(b []byte) {
|
||||||
|
native := NativeEndian()
|
||||||
|
msg.XfrmUsersaInfo.write(b[0:SizeofXfrmUsersaInfo])
|
||||||
|
native.PutUint32(b[SizeofXfrmUsersaInfo:SizeofXfrmUsersaInfo+4], msg.Min)
|
||||||
|
native.PutUint32(b[SizeofXfrmUsersaInfo+4:SizeofXfrmUsersaInfo+8], msg.Max)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *XfrmUserSpiInfo) serializeSafe() []byte {
|
||||||
|
b := make([]byte, SizeofXfrmUserSpiInfo)
|
||||||
|
msg.write(b)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func deserializeXfrmUserSpiInfoSafe(b []byte) *XfrmUserSpiInfo {
|
||||||
|
var msg = XfrmUserSpiInfo{}
|
||||||
|
binary.Read(bytes.NewReader(b[0:SizeofXfrmUserSpiInfo]), NativeEndian(), &msg)
|
||||||
|
return &msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXfrmUserSpiInfoDeserializeSerialize(t *testing.T) {
|
||||||
|
var orig = make([]byte, SizeofXfrmUserSpiInfo)
|
||||||
|
rand.Read(orig)
|
||||||
|
safemsg := deserializeXfrmUserSpiInfoSafe(orig)
|
||||||
|
msg := DeserializeXfrmUserSpiInfo(orig)
|
||||||
|
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||||
|
}
|
||||||
|
|
||||||
func deserializeXfrmAlgoSafe(b []byte) *XfrmAlgo {
|
func deserializeXfrmAlgoSafe(b []byte) *XfrmAlgo {
|
||||||
var msg = XfrmAlgo{}
|
var msg = XfrmAlgo{}
|
||||||
copy(msg.AlgName[:], b[0:64])
|
copy(msg.AlgName[:], b[0:64])
|
||||||
|
@@ -72,6 +72,12 @@ func (h *Handle) XfrmStateAdd(state *XfrmState) error {
|
|||||||
return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_NEWSA)
|
return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_NEWSA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XfrmStateAllocSpi will allocate an xfrm state in the system.
|
||||||
|
// Equivalent to: `ip xfrm state allocspi`
|
||||||
|
func XfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||||
|
return pkgHandle.xfrmStateAllocSpi(state)
|
||||||
|
}
|
||||||
|
|
||||||
// XfrmStateUpdate will update an xfrm state to the system.
|
// XfrmStateUpdate will update an xfrm state to the system.
|
||||||
// Equivalent to: `ip xfrm state update $state`
|
// Equivalent to: `ip xfrm state update $state`
|
||||||
func XfrmStateUpdate(state *XfrmState) error {
|
func XfrmStateUpdate(state *XfrmState) error {
|
||||||
@@ -91,15 +97,7 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
|||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := &nl.XfrmUsersaInfo{}
|
msg := xfrmUsersaInfoFromXfrmState(state)
|
||||||
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
|
||||||
msg.Id.Daddr.FromIP(state.Dst)
|
|
||||||
msg.Saddr.FromIP(state.Src)
|
|
||||||
msg.Id.Proto = uint8(state.Proto)
|
|
||||||
msg.Mode = uint8(state.Mode)
|
|
||||||
msg.Id.Spi = nl.Swap32(uint32(state.Spi))
|
|
||||||
msg.Reqid = uint32(state.Reqid)
|
|
||||||
msg.ReplayWindow = uint8(state.ReplayWindow)
|
|
||||||
limitsToLft(state.Limits, &msg.Lft)
|
limitsToLft(state.Limits, &msg.Lft)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
@@ -134,6 +132,35 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||||
|
req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI,
|
||||||
|
syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
|
|
||||||
|
msg := &nl.XfrmUserSpiInfo{}
|
||||||
|
msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state))
|
||||||
|
// 1-255 is reserved by IANA for future use
|
||||||
|
msg.Min = 0x100
|
||||||
|
msg.Max = 0xffffffff
|
||||||
|
req.AddData(msg)
|
||||||
|
|
||||||
|
if state.Mark != nil {
|
||||||
|
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
|
||||||
|
req.AddData(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
msgs, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := parseXfrmState(msgs[0], FAMILY_ALL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
// XfrmStateDel will delete an xfrm state from the system. Note that
|
// XfrmStateDel will delete an xfrm state from the system. Note that
|
||||||
// the Algos are ignored when matching the state to delete.
|
// the Algos are ignored when matching the state to delete.
|
||||||
// Equivalent to: `ip xfrm state del $state`
|
// Equivalent to: `ip xfrm state del $state`
|
||||||
@@ -372,3 +399,17 @@ func limitsToLft(lmts XfrmStateLimits, lft *nl.XfrmLifetimeCfg) {
|
|||||||
func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
|
func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
|
||||||
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
|
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
|
||||||
|
msg := &nl.XfrmUsersaInfo{}
|
||||||
|
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
||||||
|
msg.Id.Daddr.FromIP(state.Dst)
|
||||||
|
msg.Saddr.FromIP(state.Src)
|
||||||
|
msg.Id.Proto = uint8(state.Proto)
|
||||||
|
msg.Mode = uint8(state.Mode)
|
||||||
|
msg.Id.Spi = nl.Swap32(uint32(state.Spi))
|
||||||
|
msg.Reqid = uint32(state.Reqid)
|
||||||
|
msg.ReplayWindow = uint8(state.ReplayWindow)
|
||||||
|
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
@@ -59,6 +59,26 @@ func testXfrmStateAddGetDel(t *testing.T, state *XfrmState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestXfrmStateAllocSpi(t *testing.T) {
|
||||||
|
setUpNetlinkTest(t)()
|
||||||
|
|
||||||
|
state := getBaseState()
|
||||||
|
state.Spi = 0
|
||||||
|
state.Auth = nil
|
||||||
|
state.Crypt = nil
|
||||||
|
rstate, err := XfrmStateAllocSpi(state)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if rstate.Spi == 0 {
|
||||||
|
t.Fatalf("SPI is not allocated")
|
||||||
|
}
|
||||||
|
rstate.Spi = 0
|
||||||
|
if !compareStates(state, rstate) {
|
||||||
|
t.Fatalf("State not properly allocated")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestXfrmStateFlush(t *testing.T) {
|
func TestXfrmStateFlush(t *testing.T) {
|
||||||
setUpNetlinkTest(t)()
|
setUpNetlinkTest(t)()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user