mirror of
https://github.com/vishvananda/netlink
synced 2024-12-29 02:02:21 +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"
|
||||
}
|
||||
|
||||
// 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
|
||||
type Gretap struct {
|
||||
LinkAttrs
|
||||
|
@ -1404,6 +1404,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:
|
||||
@ -1667,6 +1669,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":
|
||||
@ -1716,6 +1720,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":
|
||||
@ -2452,6 +2458,56 @@ 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))
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
other, ok := result.(*Gretap)
|
||||
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) {
|
||||
if actual.IKey != expected.IKey {
|
||||
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}})
|
||||
}
|
||||
|
||||
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) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
@ -173,6 +173,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
|
||||
|
Loading…
Reference in New Issue
Block a user