mirror of
https://github.com/vishvananda/netlink
synced 2024-12-31 19:22:02 +00:00
Add Geneve link support
Heavily based on the existing Gretap support
This commit is contained in:
parent
e440572571
commit
d185ffdb62
24
link.go
24
link.go
@ -851,6 +851,30 @@ func (b *BondSlave) SlaveType() string {
|
|||||||
return "bond"
|
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
|
||||||
|
UdpZeroCsum6Tx uint8
|
||||||
|
UdpZeroCsum6Rx 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
|
// Gretap devices must specify LocalIP and RemoteIP on create
|
||||||
type Gretap struct {
|
type Gretap struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
|
@ -1404,6 +1404,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
|||||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||||
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
|
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
|
||||||
}
|
}
|
||||||
|
case *Geneve:
|
||||||
|
addGeneveAttrs(link, linkInfo)
|
||||||
case *Gretap:
|
case *Gretap:
|
||||||
addGretapAttrs(link, linkInfo)
|
addGretapAttrs(link, linkInfo)
|
||||||
case *Iptun:
|
case *Iptun:
|
||||||
@ -1667,6 +1669,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
|||||||
link = &Macvlan{}
|
link = &Macvlan{}
|
||||||
case "macvtap":
|
case "macvtap":
|
||||||
link = &Macvtap{}
|
link = &Macvtap{}
|
||||||
|
case "geneve":
|
||||||
|
link = &Geneve{}
|
||||||
case "gretap":
|
case "gretap":
|
||||||
link = &Gretap{}
|
link = &Gretap{}
|
||||||
case "ip6gretap":
|
case "ip6gretap":
|
||||||
@ -1716,6 +1720,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
|||||||
parseMacvlanData(link, data)
|
parseMacvlanData(link, data)
|
||||||
case "macvtap":
|
case "macvtap":
|
||||||
parseMacvtapData(link, data)
|
parseMacvtapData(link, data)
|
||||||
|
case "geneve":
|
||||||
|
parseGeneveData(link, data)
|
||||||
case "gretap":
|
case "gretap":
|
||||||
parseGretapData(link, data)
|
parseGretapData(link, data)
|
||||||
case "ip6gretap":
|
case "ip6gretap":
|
||||||
@ -2452,6 +2458,56 @@ func linkFlags(rawFlags uint32) net.Flags {
|
|||||||
return f
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if geneve.ID != 0 {
|
||||||
|
data.AddRtAttr(nl.IFLA_GENEVE_ID, htonl(geneve.ID))
|
||||||
|
}
|
||||||
|
|
||||||
|
if geneve.Dport != 0 {
|
||||||
|
data.AddRtAttr(nl.IFLA_GENEVE_PORT, htons(geneve.Dport))
|
||||||
|
}
|
||||||
|
|
||||||
|
if geneve.Ttl != 0 {
|
||||||
|
data.AddRtAttr(nl.IFLA_GENEVE_TTL, nl.Uint8Attr(geneve.Ttl))
|
||||||
|
}
|
||||||
|
|
||||||
|
if geneve.Tos != 0 {
|
||||||
|
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:
|
||||||
|
geneve.ID = ntohl(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) {
|
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
||||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||||
|
|
||||||
|
48
link_test.go
48
link_test.go
@ -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 {
|
if gretap, ok := link.(*Gretap); ok {
|
||||||
other, ok := result.(*Gretap)
|
other, ok := result.(*Gretap)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -293,6 +301,31 @@ 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the Dport to 6081 (the linux default) if it wasn't specified at creation
|
||||||
|
if expected.Dport == 0 {
|
||||||
|
expected.Dport = 6081
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
func compareGretap(t *testing.T, expected, actual *Gretap) {
|
||||||
if actual.IKey != expected.IKey {
|
if actual.IKey != expected.IKey {
|
||||||
t.Fatal("Gretap.IKey doesn't match")
|
t.Fatal("Gretap.IKey doesn't match")
|
||||||
@ -575,6 +608,21 @@ func TestLinkAddDelBridge(t *testing.T) {
|
|||||||
testLinkAddDel(t, &Bridge{LinkAttrs: LinkAttrs{Name: "foo", MTU: 1400}})
|
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", EncapType: "geneve"},
|
||||||
|
ID: 0x1000,
|
||||||
|
Remote: net.IPv4(127, 0, 0, 1)})
|
||||||
|
|
||||||
|
testLinkAddDel(t, &Geneve{
|
||||||
|
LinkAttrs: LinkAttrs{Name: "foo6", EncapType: "geneve"},
|
||||||
|
ID: 0x1000,
|
||||||
|
Remote: net.ParseIP("2001:db8:ef33::2")})
|
||||||
|
}
|
||||||
|
|
||||||
func TestLinkAddDelGretap(t *testing.T) {
|
func TestLinkAddDelGretap(t *testing.T) {
|
||||||
tearDown := setUpNetlinkTest(t)
|
tearDown := setUpNetlinkTest(t)
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
@ -173,6 +173,22 @@ const (
|
|||||||
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
|
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 (
|
const (
|
||||||
IFLA_GRE_UNSPEC = iota
|
IFLA_GRE_UNSPEC = iota
|
||||||
IFLA_GRE_LINK
|
IFLA_GRE_LINK
|
||||||
|
Loading…
Reference in New Issue
Block a user