Add Mark field to xrfm state and policy (#110)

* Add Mark to xrfm state

Signed-off-by: Alessandro Boch <aboch@docker.com>

* Add Mark to xfrm policies

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2016-04-30 20:31:59 -07:00 committed by Vish Ishaya
parent d09ee68ad5
commit 18e9389da5
9 changed files with 102 additions and 1 deletions

View File

@ -78,6 +78,7 @@ const (
SizeofXfrmLifetimeCfg = 0x40
SizeofXfrmLifetimeCur = 0x20
SizeofXfrmId = 0x18
SizeofXfrmMark = 0x08
)
// typedef union {
@ -256,3 +257,20 @@ func DeserializeXfrmId(b []byte) *XfrmId {
func (msg *XfrmId) Serialize() []byte {
return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:]
}
type XfrmMark struct {
Value uint32
Mask uint32
}
func (msg *XfrmMark) Len() int {
return SizeofXfrmMark
}
func DeserializeXfrmMark(b []byte) *XfrmMark {
return (*XfrmMark)(unsafe.Pointer(&b[0:SizeofXfrmMark][0]))
}
func (msg *XfrmMark) Serialize() []byte {
return (*(*[SizeofXfrmMark]byte)(unsafe.Pointer(msg)))[:]
}

View File

@ -205,3 +205,29 @@ func TestXfrmEncapTmplDeserializeSerialize(t *testing.T) {
msg := DeserializeXfrmEncapTmpl(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *XfrmMark) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], msg.Value)
native.PutUint32(b[4:8], msg.Mask)
}
func (msg *XfrmMark) serializeSafe() []byte {
b := make([]byte, SizeofXfrmMark)
msg.write(b)
return b
}
func deserializeXfrmMarkSafe(b []byte) *XfrmMark {
var msg = XfrmMark{}
binary.Read(bytes.NewReader(b[0:SizeofXfrmMark]), NativeEndian(), &msg)
return &msg
}
func TestXfrmMarkDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofXfrmMark)
rand.Read(orig)
safemsg := deserializeXfrmMarkSafe(orig)
msg := DeserializeXfrmMark(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}

10
xfrm.go
View File

@ -62,3 +62,13 @@ func (m Mode) String() string {
}
return fmt.Sprintf("%d", m)
}
// XfrmMark represents the mark associated to the state or policy
type XfrmMark struct {
Value uint32
Mask uint32
}
func (m *XfrmMark) String() string {
return fmt.Sprintf("(0x%x,0x%x)", m.Value, m.Mask)
}

View File

@ -55,5 +55,6 @@ type XfrmPolicy struct {
Dir Dir
Priority int
Index int
Mark *XfrmMark
Tmpls []XfrmPolicyTmpl
}

View File

@ -49,6 +49,10 @@ func XfrmPolicyAdd(policy *XfrmPolicy) error {
tmpls := nl.NewRtAttr(nl.XFRMA_TMPL, tmplData)
req.AddData(tmpls)
}
if policy.Mark != nil {
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark))
req.AddData(out)
}
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
return err
@ -66,6 +70,11 @@ func XfrmPolicyDel(policy *XfrmPolicy) error {
msg.Dir = uint8(policy.Dir)
req.AddData(msg)
if policy.Mark != nil {
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark))
req.AddData(out)
}
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
return err
}
@ -119,6 +128,11 @@ func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
resTmpl.Reqid = int(tmpl.Reqid)
policy.Tmpls = append(policy.Tmpls, resTmpl)
}
case nl.XFRMA_MARK:
mark := nl.DeserializeXfrmMark(attr.Value[:])
policy.Mark = new(XfrmMark)
policy.Mark.Value = mark.Value
policy.Mark.Mask = mark.Mask
}
}
res = append(res, policy)

View File

@ -15,6 +15,10 @@ func TestXfrmPolicyAddDel(t *testing.T) {
Src: src,
Dst: dst,
Dir: XFRM_DIR_OUT,
Mark: &XfrmMark{
Value: 0xabff22,
Mask: 0xffffffff,
},
}
tmpl := XfrmPolicyTmpl{
Src: net.ParseIP("127.0.0.1"),

View File

@ -47,6 +47,7 @@ type XfrmState struct {
Spi int
Reqid int
ReplayWindow int
Mark *XfrmMark
Auth *XfrmStateAlgo
Crypt *XfrmStateAlgo
Encap *XfrmStateEncap

View File

@ -34,6 +34,17 @@ func writeStateAlgoAuth(a *XfrmStateAlgo) []byte {
return algo.Serialize()
}
func writeMark(m *XfrmMark) []byte {
mark := &nl.XfrmMark{
Value: m.Value,
Mask: m.Mask,
}
if mark.Mask == 0 {
mark.Mask = 0xfffffff
}
return mark.Serialize()
}
// XfrmStateAdd will add an xfrm state to the system.
// Equivalent to: `ip xfrm state add $state`
func XfrmStateAdd(state *XfrmState) error {
@ -76,6 +87,10 @@ func XfrmStateAdd(state *XfrmState) error {
out := nl.NewRtAttr(nl.XFRMA_ENCAP, encapData)
req.AddData(out)
}
if state.Mark != nil {
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
req.AddData(out)
}
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
return err
@ -99,7 +114,10 @@ func XfrmStateDel(state *XfrmState) error {
srcdata := nl.NewRtAttr(nl.XFRMA_SRCADDR, saddr.Serialize())
req.AddData(srcdata)
if state.Mark != nil {
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
req.AddData(out)
}
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
return err
}
@ -169,6 +187,11 @@ func XfrmStateList(family int) ([]XfrmState, error) {
state.Encap.SrcPort = int(nl.Swap16(encap.EncapSport))
state.Encap.DstPort = int(nl.Swap16(encap.EncapDport))
state.Encap.OriginalAddress = encap.EncapOa.ToIP()
case nl.XFRMA_MARK:
mark := nl.DeserializeXfrmMark(attr.Value[:])
state.Mark = new(XfrmMark)
state.Mark.Value = mark.Value
state.Mark.Mask = mark.Mask
}
}

View File

@ -23,6 +23,10 @@ func TestXfrmStateAddDel(t *testing.T) {
Name: "cbc(aes)",
Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
},
Mark: &XfrmMark{
Value: 0x12340000,
Mask: 0xffff0000,
},
}
if err := XfrmStateAdd(&state); err != nil {
t.Fatal(err)