mirror of https://github.com/vishvananda/netlink
Add support for XfrmState Encapsulation
This commit is contained in:
parent
88c13bcb5c
commit
c074f56200
|
@ -11,16 +11,44 @@ type XfrmStateAlgo struct {
|
|||
TruncateLen int // Auth only
|
||||
}
|
||||
|
||||
// EncapType is an enum representing an ipsec template direction.
|
||||
type EncapType uint8
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota
|
||||
XFRM_ENCAP_ESPINUDP EncapType = iota
|
||||
)
|
||||
|
||||
func (e EncapType) String() string {
|
||||
switch e {
|
||||
case XFRM_ENCAP_ESPINUDP_NONIKE:
|
||||
return "espinudp-nonike"
|
||||
case XFRM_ENCAP_ESPINUDP:
|
||||
return "espinudp"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// XfrmEncap represents the encapsulation to use for the ipsec encryption.
|
||||
type XfrmStateEncap struct {
|
||||
Type EncapType
|
||||
SrcPort int
|
||||
DstPort int
|
||||
OriginalAddress net.IP
|
||||
}
|
||||
|
||||
// XfrmState represents the state of an ipsec policy. It optionally
|
||||
// contains an XfrmStateAlgo for encryption and one for authentication.
|
||||
type XfrmState struct {
|
||||
Dst net.IP
|
||||
Src net.IP
|
||||
Proto Proto
|
||||
Mode Mode
|
||||
Spi int
|
||||
Reqid int
|
||||
Dst net.IP
|
||||
Src net.IP
|
||||
Proto Proto
|
||||
Mode Mode
|
||||
Spi int
|
||||
Reqid int
|
||||
ReplayWindow int
|
||||
Auth *XfrmStateAlgo
|
||||
Crypt *XfrmStateAlgo
|
||||
Auth *XfrmStateAlgo
|
||||
Crypt *XfrmStateAlgo
|
||||
Encap *XfrmStateEncap
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ const (
|
|||
SizeofXfrmUsersaInfo = 0xe0
|
||||
SizeofXfrmAlgo = 0x44
|
||||
SizeofXfrmAlgoAuth = 0x48
|
||||
SizeofXfrmEncapTmpl = 0x18
|
||||
)
|
||||
|
||||
// struct xfrm_usersa_id {
|
||||
|
@ -201,6 +202,26 @@ func (msg *XfrmAlgoAuth) Serialize() []byte {
|
|||
// xfrm_address_t encap_oa;
|
||||
// };
|
||||
|
||||
type XfrmEncapTmpl struct {
|
||||
EncapType uint16
|
||||
EncapSport uint16 // big endian
|
||||
EncapDport uint16 // big endian
|
||||
Pad [2]byte
|
||||
EncapOa XfrmAddress
|
||||
}
|
||||
|
||||
func (msg *XfrmEncapTmpl) Len() int {
|
||||
return SizeofXfrmEncapTmpl
|
||||
}
|
||||
|
||||
func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl {
|
||||
return (*XfrmEncapTmpl)(unsafe.Pointer(&b[0:SizeofXfrmEncapTmpl][0]))
|
||||
}
|
||||
|
||||
func (msg *XfrmEncapTmpl) Serialize() []byte {
|
||||
return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
func writeStateAlgo(a *XfrmStateAlgo) []byte {
|
||||
algo := XfrmAlgo{
|
||||
AlgKeyLen: uint32(len(a.Key) * 8),
|
||||
|
@ -260,6 +281,16 @@ func XfrmStateAdd(state *XfrmState) error {
|
|||
out := newRtAttr(XFRMA_ALG_CRYPT, writeStateAlgo(state.Crypt))
|
||||
req.AddData(out)
|
||||
}
|
||||
if state.Encap != nil {
|
||||
encapData := make([]byte, SizeofXfrmEncapTmpl)
|
||||
encap := DeserializeXfrmEncapTmpl(encapData)
|
||||
encap.EncapType = uint16(state.Encap.Type)
|
||||
encap.EncapSport = swap16(uint16(state.Encap.SrcPort))
|
||||
encap.EncapDport = swap16(uint16(state.Encap.DstPort))
|
||||
encap.EncapOa.FromIP(state.Encap.OriginalAddress)
|
||||
out := newRtAttr(XFRMA_ENCAP, encapData)
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||
return err
|
||||
|
@ -349,6 +380,13 @@ func XfrmStateList(family int) ([]XfrmState, error) {
|
|||
state.Auth.Name = bytesToString(algo.AlgName[:])
|
||||
state.Auth.Key = algo.AlgKey
|
||||
state.Auth.TruncateLen = int(algo.AlgTruncLen)
|
||||
case XFRMA_ENCAP:
|
||||
encap := DeserializeXfrmEncapTmpl(attr.Value[:])
|
||||
state.Encap = new(XfrmStateEncap)
|
||||
state.Encap.Type = EncapType(encap.EncapType)
|
||||
state.Encap.SrcPort = int(swap16(encap.EncapSport))
|
||||
state.Encap.DstPort = int(swap16(encap.EncapDport))
|
||||
state.Encap.OriginalAddress = encap.EncapOa.ToIP()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -176,3 +176,32 @@ func TestXfrmAlgoAuthDeserializeSerialize(t *testing.T) {
|
|||
msg := DeserializeXfrmAlgoAuth(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmEncapTmpl) write(b []byte) {
|
||||
native := nativeEndian()
|
||||
native.PutUint16(b[0:2], msg.EncapType)
|
||||
native.PutUint16(b[2:4], msg.EncapSport)
|
||||
native.PutUint16(b[4:6], msg.EncapDport)
|
||||
copy(b[6:8], msg.Pad[:])
|
||||
msg.EncapOa.write(b[8:SizeofXfrmAddress])
|
||||
}
|
||||
|
||||
func (msg *XfrmEncapTmpl) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmEncapTmpl)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmEncapTmplSafe(b []byte) *XfrmEncapTmpl {
|
||||
var msg = XfrmEncapTmpl{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmEncapTmpl]), nativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmEncapTmplDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmEncapTmpl)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmEncapTmplSafe(orig)
|
||||
msg := DeserializeXfrmEncapTmpl(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue