From c5d79eb2c1101aed0339e9959006d39bc9aa0dea Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Tue, 28 Jan 2020 14:40:09 -0800 Subject: [PATCH] ipv6: Add support for ipv6 for netmon as well. Netmon should now handle ipv6 addresses and routes as well. Signed-off-by: Archana Shinde --- netmon/netmon.go | 36 +++++++++++++--------- netmon/netmon_test.go | 71 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/netmon/netmon.go b/netmon/netmon.go index b4b74ad120..94305ce2c0 100644 --- a/netmon/netmon.go +++ b/netmon/netmon.go @@ -52,7 +52,7 @@ var ( version = "unknown" // For simplicity the code will only focus on IPv4 addresses for now. - netlinkFamily = netlink.FAMILY_V4 + netlinkFamily = netlink.FAMILY_ALL storageParentPath = "/var/run/kata-containers/netmon/sbs" ) @@ -275,11 +275,16 @@ func convertInterface(linkAttrs *netlink.LinkAttrs, linkType string, addrs []net netMask, _ := addr.Mask.Size() ipAddr := &vcTypes.IPAddress{ - Family: netlinkFamily, Address: addr.IP.String(), Mask: fmt.Sprintf("%d", netMask), } + if addr.IP.To4() != nil { + ipAddr.Family = netlink.FAMILY_V4 + } else { + ipAddr.Family = netlink.FAMILY_V6 + } + ipAddrs = append(ipAddrs, ipAddr) } @@ -303,8 +308,6 @@ func convertInterface(linkAttrs *netlink.LinkAttrs, linkType string, addrs []net func convertRoutes(netRoutes []netlink.Route) []vcTypes.Route { var routes []vcTypes.Route - // Ignore routes with IPv6 addresses as this is not supported - // by Kata yet. for _, netRoute := range netRoutes { dst := "" @@ -313,25 +316,30 @@ func convertRoutes(netRoutes []netlink.Route) []vcTypes.Route { } if netRoute.Dst != nil { - if netRoute.Dst.IP.To4() != nil { + dst = netRoute.Dst.String() + if netRoute.Dst.IP.To4() != nil || netRoute.Dst.IP.To16() != nil { dst = netRoute.Dst.String() } else { - netmonLog.WithField("destination", netRoute.Dst.IP.String()).Warn("Not IPv4 format") + netmonLog.WithField("destination", netRoute.Dst.IP.String()).Warn("Unexpected network address format") } } src := "" - if netRoute.Src.To4() != nil { - src = netRoute.Src.String() - } else { - netmonLog.WithField("source", netRoute.Src.String()).Warn("Not IPv4 format") + if netRoute.Src != nil { + if netRoute.Src.To4() != nil || netRoute.Src.To16() != nil { + src = netRoute.Src.String() + } else { + netmonLog.WithField("source", netRoute.Src.String()).Warn("Unexpected network address format") + } } gw := "" - if netRoute.Gw.To4() != nil { - gw = netRoute.Gw.String() - } else { - netmonLog.WithField("gateway", netRoute.Gw.String()).Warn("Not IPv4 format") + if netRoute.Gw != nil { + if netRoute.Gw.To4() != nil || netRoute.Gw.To16() != nil { + gw = netRoute.Gw.String() + } else { + netmonLog.WithField("gateway", netRoute.Gw.String()).Warn("Unexpected network address format") + } } dev := "" diff --git a/netmon/netmon_test.go b/netmon/netmon_test.go index 98dede6eb0..e214880641 100644 --- a/netmon/netmon_test.go +++ b/netmon/netmon_test.go @@ -7,6 +7,7 @@ package main import ( "encoding/json" + "fmt" "io/ioutil" "net" "os" @@ -37,6 +38,8 @@ const ( testHwAddr = "02:00:ca:fe:00:48" testIPAddress = "192.168.0.15" testIPAddressWithMask = "192.168.0.15/32" + testIP6Address = "2001:db8:1::242:ac11:2" + testIP6AddressWithMask = "2001:db8:1::/64" testScope = 1 testTxQLen = -1 testIfaceIndex = 5 @@ -169,6 +172,11 @@ func TestConvertInterface(t *testing.T) { IP: net.ParseIP(testIPAddress), }, }, + { + IPNet: &net.IPNet{ + IP: net.ParseIP(testIP6Address), + }, + }, } linkAttrs := &netlink.LinkAttrs{ @@ -186,15 +194,21 @@ func TestConvertInterface(t *testing.T) { HwAddr: testHwAddr, IPAddresses: []*vcTypes.IPAddress{ { - Family: netlinkFamily, + Family: netlink.FAMILY_V4, Address: testIPAddress, Mask: "0", }, + { + Family: netlink.FAMILY_V6, + Address: testIP6Address, + Mask: "0", + }, }, LinkType: linkType, } got := convertInterface(linkAttrs, linkType, addrs) + assert.True(t, reflect.DeepEqual(expected, got), "Got %+v\nExpected %+v", got, expected) } @@ -204,6 +218,10 @@ func TestConvertRoutes(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, ipNet) + _, ip6Net, err := net.ParseCIDR(testIP6AddressWithMask) + assert.Nil(t, err) + assert.NotNil(t, ipNet) + routes := []netlink.Route{ { Dst: ipNet, @@ -212,6 +230,13 @@ func TestConvertRoutes(t *testing.T) { LinkIndex: -1, Scope: testScope, }, + { + Dst: ip6Net, + Src: nil, + Gw: nil, + LinkIndex: -1, + Scope: testScope, + }, } expected := []vcTypes.Route{ @@ -221,6 +246,12 @@ func TestConvertRoutes(t *testing.T) { Source: testIPAddress, Scope: uint32(testScope), }, + { + Dest: testIP6AddressWithMask, + Gateway: "", + Source: "", + Scope: uint32(testScope), + }, } got := convertRoutes(routes) @@ -269,12 +300,40 @@ func testCreateDummyNetwork(t *testing.T, handler *netlink.Handle) (int, vcTypes attrs := link.Attrs() assert.NotNil(t, attrs) + addrs, err := handler.AddrList(link, netlinkFamily) + assert.Nil(t, err) + + var ipAddrs []*vcTypes.IPAddress + + // Scan addresses for ipv6 link local address which is automatically assigned + for _, addr := range addrs { + if addr.IPNet == nil { + continue + } + + netMask, _ := addr.Mask.Size() + + ipAddr := &vcTypes.IPAddress{ + Address: addr.IP.String(), + Mask: fmt.Sprintf("%d", netMask), + } + + if addr.IP.To4() != nil { + ipAddr.Family = netlink.FAMILY_V4 + } else { + ipAddr.Family = netlink.FAMILY_V6 + } + + ipAddrs = append(ipAddrs, ipAddr) + } + iface := vcTypes.Interface{ - Device: testIfaceName, - Name: testIfaceName, - Mtu: uint64(testMTU), - HwAddr: testHwAddr, - LinkType: link.Type(), + Device: testIfaceName, + Name: testIfaceName, + Mtu: uint64(testMTU), + HwAddr: testHwAddr, + LinkType: link.Type(), + IPAddresses: ipAddrs, } return attrs.Index, iface