Merge pull request #3592 from balopat/fix_netstat

fix netstat -f error on linux distros
pull/3600/head
Kubernetes Prow Robot 2019-01-28 13:55:21 -08:00 committed by GitHub
commit 7ccfe517b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 30 deletions

View File

@ -54,7 +54,7 @@ func (router *osRouter) EnsureRouteIsAdded(route *Route) error {
}
func (router *osRouter) Inspect(route *Route) (exists bool, conflict string, overlaps []string, err error) {
cmd := exec.Command("netstat", "-nr", "-f", "inet")
cmd := exec.Command("ip", "r")
cmd.Env = append(cmd.Env, "LC_ALL=C")
stdInAndOut, err := cmd.CombinedOutput()
if err != nil {
@ -70,37 +70,39 @@ func (router *osRouter) Inspect(route *Route) (exists bool, conflict string, ove
func (router *osRouter) parseTable(table []byte) routingTable {
t := routingTable{}
skip := true
for _, line := range strings.Split(string(table), "\n") {
//after first line of header we can start consuming
if strings.HasPrefix(line, "Destination") {
skip = false
continue
}
fields := strings.Fields(line)
//don't care about the 0.0.0.0 routes
if skip || len(fields) == 0 || len(fields) > 0 && (fields[0] == "default" || fields[0] == "0.0.0.0") {
//don't care about the routes that 0.0.0.0
if len(fields) == 0 ||
len(fields) > 0 && (fields[0] == "default" || fields[0] == "0.0.0.0") {
continue
}
if len(fields) > 2 {
dstCIDRIP := net.ParseIP(fields[0])
dstCIDRMask := fields[2]
dstMaskIP := net.ParseIP(dstCIDRMask)
gatewayIP := net.ParseIP(fields[1])
if dstCIDRIP == nil || gatewayIP == nil || dstMaskIP == nil {
glog.V(8).Infof("skipping line: can't parse: %s", line)
//assuming "10.96.0.0/12 via 192.168.39.47 dev virbr1"
dstCIDRString := fields[0]
gatewayIPString := fields[2]
gatewayIP := net.ParseIP(gatewayIPString)
//if not via format, then gateway is assumed to be 0.0.0.0
// "1.2.3.0/24 dev eno1 proto kernel scope link src 1.2.3.54 metric 100"
if fields[1] != "via" {
gatewayIP = net.ParseIP("0.0.0.0")
}
_, ipNet, err := net.ParseCIDR(dstCIDRString)
if err != nil {
glog.V(4).Infof("skipping line: can't parse CIDR from routing table: %s", dstCIDRString)
} else if gatewayIP == nil {
glog.V(4).Infof("skipping line: can't parse IP from routing table: %s", gatewayIPString)
} else {
dstCIDR := &net.IPNet{
IP: dstCIDRIP,
Mask: net.IPv4Mask(dstMaskIP[12], dstMaskIP[13], dstMaskIP[14], dstMaskIP[15]),
}
tableLine := routingTableLine{
route: &Route{
DestCIDR: dstCIDR,
DestCIDR: ipNet,
Gateway: gatewayIP,
},
line: line,

View File

@ -90,23 +90,30 @@ func TestLinuxRouteCleanupIdempontentIntegrationTest(t *testing.T) {
func TestParseTable(t *testing.T) {
const table = `Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.31.126.254 0.0.0.0 UG 0 0 0 eno1
10.96.0.0 127.0.0.1 255.240.0.0 UG 0 0 0 eno1
172.31.126.0 0.0.0.0 255.255.255.0 U 0 0 0 eno1
`
const table = `default via 172.31.126.254 dev eno1 proto dhcp metric 100
10.96.0.0/12 via 192.168.39.47 dev virbr1
10.110.0.0/16 via 127.0.0.1 dev lo
172.31.126.0/24 dev eno1 proto kernel scope link src 172.31.126.54 metric 100
192.168.9.0/24 dev docker0 proto kernel scope link src 192.168.9.1`
rt := (&osRouter{}).parseTable([]byte(table))
expectedRt := routingTable{
routingTableLine{
route: unsafeParseRoute("127.0.0.1", "10.96.0.0/12"),
line: "10.96.0.0 127.0.0.1 255.240.0.0 UG 0 0 0 eno1",
route: unsafeParseRoute("192.168.39.47", "10.96.0.0/12"),
line: "10.96.0.0/12 via 192.168.39.47 dev virbr1",
},
routingTableLine{
route: unsafeParseRoute("127.0.0.1", "10.110.0.0/16"),
line: "10.110.0.0/16 via 127.0.0.1 dev lo",
},
routingTableLine{
route: unsafeParseRoute("0.0.0.0", "172.31.126.0/24"),
line: "172.31.126.0 0.0.0.0 255.255.255.0 U 0 0 0 eno1",
line: "172.31.126.0/24 dev eno1 proto kernel scope link src 172.31.126.54 metric 100",
},
routingTableLine{
route: unsafeParseRoute("0.0.0.0", "192.168.9.0/24"),
line: "192.168.9.0/24 dev docker0 proto kernel scope link src 192.168.9.1",
},
}
if !expectedRt.Equal(&rt) {