link: Add support for IFLA_*_COLLECT_METADATA

- Implemented for VXLAN and GRE via a flag `FlowBased`
- Added unit tests to verify ability

Signed-off-by: Thomas Graf <tgraf@tgraf.ch>
This commit is contained in:
Thomas Graf 2017-06-10 15:47:01 +02:00 committed by Vish (Ishaya) Abrams
parent 7593cff56f
commit 4e28683688
3 changed files with 56 additions and 0 deletions

View File

@ -339,6 +339,7 @@ type Vxlan struct {
UDPCSum bool
NoAge bool
GBP bool
FlowBased bool
Age int
Limit int
Port int
@ -684,6 +685,7 @@ type Gretap struct {
EncapType uint16
EncapFlags uint16
Link uint32
FlowBased bool
}
func (gretap *Gretap) Attrs() *LinkAttrs {

View File

@ -528,7 +528,13 @@ type vxlanPortRange struct {
func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
if vxlan.FlowBased {
vxlan.VxlanId = 0
}
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId)))
if vxlan.VtepDevIndex != 0 {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex)))
}
@ -569,6 +575,9 @@ func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
if vxlan.GBP {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GBP, []byte{})
}
if vxlan.FlowBased {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_FLOWBASED, boolAttr(vxlan.FlowBased))
}
if vxlan.NoAge {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0))
} else if vxlan.Age > 0 {
@ -1407,6 +1416,8 @@ func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
vxlan.UDPCSum = int8(datum.Value[0]) != 0
case nl.IFLA_VXLAN_GBP:
vxlan.GBP = true
case nl.IFLA_VXLAN_FLOWBASED:
vxlan.FlowBased = int8(datum.Value[0]) != 0
case nl.IFLA_VXLAN_AGEING:
vxlan.Age = int(native.Uint32(datum.Value[0:4]))
vxlan.NoAge = vxlan.Age == 0
@ -1547,6 +1558,12 @@ func linkFlags(rawFlags uint32) net.Flags {
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
if gretap.FlowBased {
// In flow based mode, no other attributes need to be configured
nl.NewRtAttrChild(data, nl.IFLA_GRE_COLLECT_METADATA, boolAttr(gretap.FlowBased))
return
}
ip := gretap.Local.To4()
if ip != nil {
nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip))
@ -1613,6 +1630,8 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
gre.EncapType = native.Uint16(datum.Value[0:2])
case nl.IFLA_GRE_ENCAP_FLAGS:
gre.EncapFlags = native.Uint16(datum.Value[0:2])
case nl.IFLA_GRE_COLLECT_METADATA:
gre.FlowBased = int8(datum.Value[0]) != 0
}
}
}

View File

@ -220,6 +220,9 @@ func compareVxlan(t *testing.T, expected, actual *Vxlan) {
if actual.GBP != expected.GBP {
t.Fatal("Vxlan.GBP doesn't match")
}
if actual.FlowBased != expected.FlowBased {
t.Fatal("Vxlan.FlowBased doesn't match")
}
if expected.NoAge {
if !actual.NoAge {
t.Fatal("Vxlan.NoAge doesn't match")
@ -277,6 +280,19 @@ func TestLinkAddDelGretap(t *testing.T) {
Remote: net.IPv4(127, 0, 0, 1)})
}
func TestLinkAddDelGretapFlowBased(t *testing.T) {
if os.Getenv("TRAVIS_BUILD_DIR") != "" {
t.Skipf("Kernel in travis is too old for this test")
}
tearDown := setUpNetlinkTest(t)
defer tearDown()
testLinkAddDel(t, &Gretap{
LinkAttrs: LinkAttrs{Name: "foo"},
FlowBased: true})
}
func TestLinkAddDelVlan(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()
@ -693,6 +709,25 @@ func TestLinkAddDelVxlanGbp(t *testing.T) {
}
}
func TestLinkAddDelVxlanFlowBased(t *testing.T) {
if os.Getenv("TRAVIS_BUILD_DIR") != "" {
t.Skipf("Kernel in travis is too old for this test")
}
tearDown := setUpNetlinkTest(t)
defer tearDown()
vxlan := Vxlan{
LinkAttrs: LinkAttrs{
Name: "foo",
},
Learning: false,
FlowBased: true,
}
testLinkAddDel(t, &vxlan)
}
func TestLinkAddDelIPVlanL2(t *testing.T) {
if os.Getenv("TRAVIS_BUILD_DIR") != "" {
t.Skipf("Kernel in travis is too old for this test")