Skip to content

Commit

Permalink
Add Geneve link support
Browse files Browse the repository at this point in the history
Heavily based on the existing Gretap support
  • Loading branch information
Stephen Hassard committed Sep 14, 2020
1 parent 3374423 commit 14baa29
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 8 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module github.com/vishvananda/netlink
go 1.12

require (
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
golang.org/x/sys v0.0.0-20200121082415-34d275377bf9
)
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
golang.org/x/sys v0.0.0-20200121082415-34d275377bf9 h1:N19i1HjUnR7TF7rMt8O4p3dLvqvmYyzB6ifMFmrbY50=
golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
24 changes: 24 additions & 0 deletions link.go
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,30 @@ func (b *BondSlave) SlaveType() string {
return "bond"
}

// Geneve devices must specify RemoteIP and ID (VNI) on create
// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223
type Geneve struct {
LinkAttrs
ID uint32 // vni
Remote net.IP
Ttl uint8
Tos uint8
Dport uint16
UdpCsum uint8
UdpZeroCsum6_Tx uint8
UdpZeroCsum6_Rx uint8
Link uint32
FlowBased bool
}

func (geneve *Geneve) Attrs() *LinkAttrs {
return &geneve.LinkAttrs
}

func (geneve *Geneve) Type() string {
return "geneve"
}

// Gretap devices must specify LocalIP and RemoteIP on create
type Gretap struct {
LinkAttrs
Expand Down
45 changes: 45 additions & 0 deletions link_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
}
case *Geneve:
addGeneveAttrs(link, linkInfo)
case *Gretap:
addGretapAttrs(link, linkInfo)
case *Iptun:
Expand Down Expand Up @@ -1636,6 +1638,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
link = &Macvlan{}
case "macvtap":
link = &Macvtap{}
case "geneve":
link = &Geneve{}
case "gretap":
link = &Gretap{}
case "ip6gretap":
Expand Down Expand Up @@ -1683,6 +1687,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
parseMacvlanData(link, data)
case "macvtap":
parseMacvtapData(link, data)
case "geneve":
parseGeneveData(link, data)
case "gretap":
parseGretapData(link, data)
case "ip6gretap":
Expand Down Expand Up @@ -2417,6 +2423,45 @@ func linkFlags(rawFlags uint32) net.Flags {
return f
}

func addGeneveAttrs(geneve *Geneve, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)

if geneve.FlowBased {
// In flow based mode, no other attributes need to be configured
linkInfo.AddRtAttr(nl.IFLA_GENEVE_COLLECT_METADATA, boolAttr(geneve.FlowBased))
return
}

if ip := geneve.Remote; ip != nil {
if ip4 := ip.To4(); ip4 != nil {
data.AddRtAttr(nl.IFLA_GENEVE_REMOTE, []byte(ip))
} else {
data.AddRtAttr(nl.IFLA_GENEVE_REMOTE6, []byte(ip))
}
}

data.AddRtAttr(nl.IFLA_GENEVE_ID, nl.Uint32Attr(geneve.ID))
data.AddRtAttr(nl.IFLA_GENEVE_PORT, htons(geneve.Dport))
data.AddRtAttr(nl.IFLA_GENEVE_TTL, nl.Uint8Attr(geneve.Ttl))
data.AddRtAttr(nl.IFLA_GENEVE_TOS, nl.Uint8Attr(geneve.Tos))
}

func parseGeneveData(link Link, data []syscall.NetlinkRouteAttr) {
geneve := link.(*Geneve)
for _, datum := range data {
switch datum.Attr.Type {
case nl.IFLA_GENEVE_ID:
native.Uint32(datum.Value[0:4])
case nl.IFLA_GENEVE_PORT:
geneve.Dport = ntohs(datum.Value[0:2])
case nl.IFLA_GENEVE_TTL:
geneve.Ttl = uint8(datum.Value[0])
case nl.IFLA_GENEVE_TOS:
geneve.Tos = uint8(datum.Value[0])
}
}
}

func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)

Expand Down
43 changes: 43 additions & 0 deletions link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ func testLinkAddDel(t *testing.T, link Link) {
}
}

if geneve, ok := link.(*Geneve); ok {
other, ok := result.(*Geneve)
if !ok {
t.Fatal("Result of create is not a Geneve")
}
compareGeneve(t, geneve, other)
}

if gretap, ok := link.(*Gretap); ok {
other, ok := result.(*Gretap)
if !ok {
Expand Down Expand Up @@ -293,6 +301,26 @@ func testLinkAddDel(t *testing.T, link Link) {
}
}

func compareGeneve(t *testing.T, expected, actual *Geneve) {
if actual.ID != expected.ID {
t.Fatalf("Geneve.ID doesn't match: %d %d", actual.ID, expected.ID)
}

if actual.Dport != expected.Dport {
t.Fatal("Geneve.Dport doesn't match")
}

if actual.Ttl != expected.Ttl {
t.Fatal("Geneve.Ttl doesn't match")
}

if actual.Tos != expected.Tos {
t.Fatal("Geneve.Tos doesn't match")
}

// TODO: we should implement the rest of the geneve methods
}

func compareGretap(t *testing.T, expected, actual *Gretap) {
if actual.IKey != expected.IKey {
t.Fatal("Gretap.IKey doesn't match")
Expand Down Expand Up @@ -575,6 +603,21 @@ func TestLinkAddDelBridge(t *testing.T) {
testLinkAddDel(t, &Bridge{LinkAttrs: LinkAttrs{Name: "foo", MTU: 1400}})
}

func TestLinkAddDelGeneve(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()

testLinkAddDel(t, &Geneve{
LinkAttrs: LinkAttrs{Name: "foo4"},
ID: 0x01,
Remote: net.IPv4(127, 0, 0, 1)})

testLinkAddDel(t, &Geneve{
LinkAttrs: LinkAttrs{Name: "foo6"},
ID: 0x01,
Remote: net.ParseIP("2001:db8:ef33::2")})
}

func TestLinkAddDelGretap(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()
Expand Down
16 changes: 16 additions & 0 deletions nl/link_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ const (
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
)

const (
IFLA_GENEVE_UNSPEC = iota
IFLA_GENEVE_ID // vni
IFLA_GENEVE_REMOTE
IFLA_GENEVE_TTL
IFLA_GENEVE_TOS
IFLA_GENEVE_PORT // destination port
IFLA_GENEVE_COLLECT_METADATA
IFLA_GENEVE_REMOTE6
IFLA_GENEVE_UDP_CSUM
IFLA_GENEVE_UDP_ZERO_CSUM6_TX
IFLA_GENEVE_UDP_ZERO_CSUM6_RX
IFLA_GENEVE_LABEL
IFLA_GENEVE_MAX = IFLA_GENEVE_LABEL
)

const (
IFLA_GRE_UNSPEC = iota
IFLA_GRE_LINK
Expand Down

0 comments on commit 14baa29

Please sign in to comment.