mirror of
https://github.com/vishvananda/netlink.git
synced 2025-09-26 20:01:13 +08:00
Add support of ESN
This commit is contained in:

committed by
Vish Ishaya

parent
6b895203a7
commit
43948793f6
@@ -5,15 +5,27 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SizeofXfrmUsersaId = 0x18
|
SizeofXfrmUsersaId = 0x18
|
||||||
SizeofXfrmStats = 0x0c
|
SizeofXfrmStats = 0x0c
|
||||||
SizeofXfrmUsersaInfo = 0xe0
|
SizeofXfrmUsersaInfo = 0xe0
|
||||||
SizeofXfrmUserSpiInfo = 0xe8
|
SizeofXfrmUserSpiInfo = 0xe8
|
||||||
SizeofXfrmAlgo = 0x44
|
SizeofXfrmAlgo = 0x44
|
||||||
SizeofXfrmAlgoAuth = 0x48
|
SizeofXfrmAlgoAuth = 0x48
|
||||||
SizeofXfrmAlgoAEAD = 0x48
|
SizeofXfrmAlgoAEAD = 0x48
|
||||||
SizeofXfrmEncapTmpl = 0x18
|
SizeofXfrmEncapTmpl = 0x18
|
||||||
SizeofXfrmUsersaFlush = 0x8
|
SizeofXfrmUsersaFlush = 0x8
|
||||||
|
SizeofXfrmReplayStateEsn = 0x18
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
XFRM_STATE_NOECN = 1
|
||||||
|
XFRM_STATE_DECAP_DSCP = 2
|
||||||
|
XFRM_STATE_NOPMTUDISC = 4
|
||||||
|
XFRM_STATE_WILDRECV = 8
|
||||||
|
XFRM_STATE_ICMP = 16
|
||||||
|
XFRM_STATE_AF_UNSPEC = 32
|
||||||
|
XFRM_STATE_ALIGN4 = 64
|
||||||
|
XFRM_STATE_ESN = 128
|
||||||
)
|
)
|
||||||
|
|
||||||
// struct xfrm_usersa_id {
|
// struct xfrm_usersa_id {
|
||||||
@@ -295,3 +307,28 @@ func DeserializeXfrmUsersaFlush(b []byte) *XfrmUsersaFlush {
|
|||||||
func (msg *XfrmUsersaFlush) Serialize() []byte {
|
func (msg *XfrmUsersaFlush) Serialize() []byte {
|
||||||
return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:]
|
return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct xfrm_replay_state_esn {
|
||||||
|
// unsigned int bmp_len;
|
||||||
|
// __u32 oseq;
|
||||||
|
// __u32 seq;
|
||||||
|
// __u32 oseq_hi;
|
||||||
|
// __u32 seq_hi;
|
||||||
|
// __u32 replay_window;
|
||||||
|
// __u32 bmp[0];
|
||||||
|
// };
|
||||||
|
|
||||||
|
type XfrmReplayStateEsn struct {
|
||||||
|
BmpLen uint32
|
||||||
|
OSeq uint32
|
||||||
|
Seq uint32
|
||||||
|
OSeqHi uint32
|
||||||
|
SeqHi uint32
|
||||||
|
ReplayWindow uint32
|
||||||
|
Bmp []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *XfrmReplayStateEsn) Serialize() []byte {
|
||||||
|
// We deliberately do not pass Bmp, as it gets set by the kernel.
|
||||||
|
return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:]
|
||||||
|
}
|
||||||
|
@@ -83,11 +83,12 @@ type XfrmState struct {
|
|||||||
Crypt *XfrmStateAlgo
|
Crypt *XfrmStateAlgo
|
||||||
Aead *XfrmStateAlgo
|
Aead *XfrmStateAlgo
|
||||||
Encap *XfrmStateEncap
|
Encap *XfrmStateEncap
|
||||||
|
ESN bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sa XfrmState) String() string {
|
func (sa XfrmState) String() string {
|
||||||
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, Auth: %v, Crypt: %v, Aead: %v,Encap: %v",
|
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t",
|
||||||
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap)
|
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
|
||||||
}
|
}
|
||||||
func (sa XfrmState) Print(stats bool) string {
|
func (sa XfrmState) Print(stats bool) string {
|
||||||
if !stats {
|
if !stats {
|
||||||
|
@@ -60,6 +60,21 @@ func writeMark(m *XfrmMark) []byte {
|
|||||||
return mark.Serialize()
|
return mark.Serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeReplayEsn(replayWindow int) []byte {
|
||||||
|
replayEsn := &nl.XfrmReplayStateEsn{
|
||||||
|
OSeq: 0,
|
||||||
|
Seq: 0,
|
||||||
|
OSeqHi: 0,
|
||||||
|
SeqHi: 0,
|
||||||
|
ReplayWindow: uint32(replayWindow),
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from iproute2/ip/xfrm_state.c:
|
||||||
|
replayEsn.BmpLen = uint32((replayWindow + (4 * 8) - 1) / (4 * 8))
|
||||||
|
|
||||||
|
return replayEsn.Serialize()
|
||||||
|
}
|
||||||
|
|
||||||
// XfrmStateAdd will add an xfrm state to the system.
|
// XfrmStateAdd will add an xfrm state to the system.
|
||||||
// Equivalent to: `ip xfrm state add $state`
|
// Equivalent to: `ip xfrm state add $state`
|
||||||
func XfrmStateAdd(state *XfrmState) error {
|
func XfrmStateAdd(state *XfrmState) error {
|
||||||
@@ -91,6 +106,7 @@ func (h *Handle) XfrmStateUpdate(state *XfrmState) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||||
|
|
||||||
// A state with spi 0 can't be deleted so don't allow it to be set
|
// A state with spi 0 can't be deleted so don't allow it to be set
|
||||||
if state.Spi == 0 {
|
if state.Spi == 0 {
|
||||||
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
||||||
@@ -98,6 +114,15 @@ 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 := xfrmUsersaInfoFromXfrmState(state)
|
msg := xfrmUsersaInfoFromXfrmState(state)
|
||||||
|
|
||||||
|
if state.ESN {
|
||||||
|
if state.ReplayWindow == 0 {
|
||||||
|
return fmt.Errorf("ESN flag set without ReplayWindow")
|
||||||
|
}
|
||||||
|
msg.Flags |= nl.XFRM_STATE_ESN
|
||||||
|
msg.ReplayWindow = 0
|
||||||
|
}
|
||||||
|
|
||||||
limitsToLft(state.Limits, &msg.Lft)
|
limitsToLft(state.Limits, &msg.Lft)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
@@ -127,6 +152,10 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
|||||||
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
|
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
|
||||||
req.AddData(out)
|
req.AddData(out)
|
||||||
}
|
}
|
||||||
|
if state.ESN {
|
||||||
|
out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
|
||||||
|
req.AddData(out)
|
||||||
|
}
|
||||||
|
|
||||||
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
return err
|
return err
|
||||||
|
Reference in New Issue
Block a user