Add XfrmAllocSpi

This commit is contained in:
Martynas Pumputis
2017-01-16 17:58:20 +00:00
committed by Vish Ishaya
parent 9a7970b3b6
commit 3c27c1c1e3
4 changed files with 122 additions and 9 deletions

View File

@@ -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 */

View File

@@ -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])

View File

@@ -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
}

View File

@@ -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)()