Merge pull request #166 from NeilW/host-loca
plugins/host-local: ensure subnet is a network address
This commit is contained in:
commit
696b1f9ab1
@ -372,7 +372,7 @@ var _ = Describe("IPAM config", func() {
|
|||||||
"type": "host-local",
|
"type": "host-local",
|
||||||
"ranges": [
|
"ranges": [
|
||||||
[{"subnet": "10.1.2.0/24"}],
|
[{"subnet": "10.1.2.0/24"}],
|
||||||
[{"subnet": "2001:db8:1::/24"}]
|
[{"subnet": "2001:db8:1::/48"}]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
@ -40,6 +40,12 @@ func (r *Range) Canonicalize() error {
|
|||||||
return fmt.Errorf("IPNet IP and Mask version mismatch")
|
return fmt.Errorf("IPNet IP and Mask version mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure Subnet IP is the network address, not some other address
|
||||||
|
networkIP := r.Subnet.IP.Mask(r.Subnet.Mask)
|
||||||
|
if !r.Subnet.IP.Equal(networkIP) {
|
||||||
|
return fmt.Errorf("Network has host bits set. For a subnet mask of length %d the network address is %s", ones, networkIP.String())
|
||||||
|
}
|
||||||
|
|
||||||
// If the gateway is nil, claim .1
|
// If the gateway is nil, claim .1
|
||||||
if r.Gateway == nil {
|
if r.Gateway == nil {
|
||||||
r.Gateway = ip.NextIP(r.Subnet.IP)
|
r.Gateway = ip.NextIP(r.Subnet.IP)
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("IP ranges", func() {
|
var _ = Describe("IP ranges", func() {
|
||||||
It("should generate sane defaults for ipv4", func() {
|
It("should generate sane defaults for ipv4 with a clean prefix", func() {
|
||||||
snstr := "192.0.2.0/24"
|
snstr := "192.0.2.0/24"
|
||||||
r := Range{Subnet: mustSubnet(snstr)}
|
r := Range{Subnet: mustSubnet(snstr)}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ var _ = Describe("IP ranges", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
Expect(r).To(Equal(Range{
|
Expect(r).To(Equal(Range{
|
||||||
Subnet: mustSubnet(snstr),
|
Subnet: networkSubnet(snstr),
|
||||||
RangeStart: net.IP{192, 0, 2, 1},
|
RangeStart: net.IP{192, 0, 2, 1},
|
||||||
RangeEnd: net.IP{192, 0, 2, 254},
|
RangeEnd: net.IP{192, 0, 2, 254},
|
||||||
Gateway: net.IP{192, 0, 2, 1},
|
Gateway: net.IP{192, 0, 2, 1},
|
||||||
@ -47,13 +47,41 @@ var _ = Describe("IP ranges", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
Expect(r).To(Equal(Range{
|
Expect(r).To(Equal(Range{
|
||||||
Subnet: mustSubnet(snstr),
|
Subnet: networkSubnet(snstr),
|
||||||
RangeStart: net.IP{192, 0, 2, 1},
|
RangeStart: net.IP{192, 0, 2, 1},
|
||||||
RangeEnd: net.IP{192, 0, 2, 126},
|
RangeEnd: net.IP{192, 0, 2, 126},
|
||||||
Gateway: net.IP{192, 0, 2, 1},
|
Gateway: net.IP{192, 0, 2, 1},
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
It("should generate sane defaults for ipv6", func() {
|
It("should reject ipv4 subnet using a masked address", func() {
|
||||||
|
snstr := "192.0.2.12/24"
|
||||||
|
r := Range{Subnet: mustSubnet(snstr)}
|
||||||
|
|
||||||
|
err := r.Canonicalize()
|
||||||
|
Expect(err).Should(MatchError("Network has host bits set. For a subnet mask of length 24 the network address is 192.0.2.0"))
|
||||||
|
})
|
||||||
|
It("should reject ipv6 subnet using a masked address", func() {
|
||||||
|
snstr := "2001:DB8:1::24:19ff:fee1:c44a/64"
|
||||||
|
r := Range{Subnet: mustSubnet(snstr)}
|
||||||
|
|
||||||
|
err := r.Canonicalize()
|
||||||
|
Expect(err).Should(MatchError("Network has host bits set. For a subnet mask of length 64 the network address is 2001:db8:1::"))
|
||||||
|
})
|
||||||
|
It("should reject ipv6 prefix with host bit set", func() {
|
||||||
|
snstr := "2001:DB8:24:19ff::/63"
|
||||||
|
r := Range{Subnet: mustSubnet(snstr)}
|
||||||
|
|
||||||
|
err := r.Canonicalize()
|
||||||
|
Expect(err).Should(MatchError("Network has host bits set. For a subnet mask of length 63 the network address is 2001:db8:24:19fe::"))
|
||||||
|
})
|
||||||
|
It("should reject ipv4 network with host bit set", func() {
|
||||||
|
snstr := "192.168.127.0/23"
|
||||||
|
r := Range{Subnet: mustSubnet(snstr)}
|
||||||
|
|
||||||
|
err := r.Canonicalize()
|
||||||
|
Expect(err).Should(MatchError("Network has host bits set. For a subnet mask of length 23 the network address is 192.168.126.0"))
|
||||||
|
})
|
||||||
|
It("should generate sane defaults for ipv6 with a clean prefix", func() {
|
||||||
snstr := "2001:DB8:1::/64"
|
snstr := "2001:DB8:1::/64"
|
||||||
r := Range{Subnet: mustSubnet(snstr)}
|
r := Range{Subnet: mustSubnet(snstr)}
|
||||||
|
|
||||||
@ -61,7 +89,7 @@ var _ = Describe("IP ranges", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
Expect(r).To(Equal(Range{
|
Expect(r).To(Equal(Range{
|
||||||
Subnet: mustSubnet(snstr),
|
Subnet: networkSubnet(snstr),
|
||||||
RangeStart: net.ParseIP("2001:DB8:1::1"),
|
RangeStart: net.ParseIP("2001:DB8:1::1"),
|
||||||
RangeEnd: net.ParseIP("2001:DB8:1::ffff:ffff:ffff:ffff"),
|
RangeEnd: net.ParseIP("2001:DB8:1::ffff:ffff:ffff:ffff"),
|
||||||
Gateway: net.ParseIP("2001:DB8:1::1"),
|
Gateway: net.ParseIP("2001:DB8:1::1"),
|
||||||
@ -75,16 +103,17 @@ var _ = Describe("IP ranges", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should reject invalid RangeStart and RangeEnd specifications", func() {
|
It("should reject invalid RangeStart and RangeEnd specifications", func() {
|
||||||
r := Range{Subnet: mustSubnet("192.0.2.0/24"), RangeStart: net.ParseIP("192.0.3.0")}
|
snstr := "192.0.2.0/24"
|
||||||
|
r := Range{Subnet: mustSubnet(snstr), RangeStart: net.ParseIP("192.0.3.0")}
|
||||||
err := r.Canonicalize()
|
err := r.Canonicalize()
|
||||||
Expect(err).Should(MatchError("RangeStart 192.0.3.0 not in network 192.0.2.0/24"))
|
Expect(err).Should(MatchError("RangeStart 192.0.3.0 not in network 192.0.2.0/24"))
|
||||||
|
|
||||||
r = Range{Subnet: mustSubnet("192.0.2.0/24"), RangeEnd: net.ParseIP("192.0.4.0")}
|
r = Range{Subnet: mustSubnet(snstr), RangeEnd: net.ParseIP("192.0.4.0")}
|
||||||
err = r.Canonicalize()
|
err = r.Canonicalize()
|
||||||
Expect(err).Should(MatchError("RangeEnd 192.0.4.0 not in network 192.0.2.0/24"))
|
Expect(err).Should(MatchError("RangeEnd 192.0.4.0 not in network 192.0.2.0/24"))
|
||||||
|
|
||||||
r = Range{
|
r = Range{
|
||||||
Subnet: mustSubnet("192.0.2.0/24"),
|
Subnet: networkSubnet(snstr),
|
||||||
RangeStart: net.ParseIP("192.0.2.50"),
|
RangeStart: net.ParseIP("192.0.2.50"),
|
||||||
RangeEnd: net.ParseIP("192.0.2.40"),
|
RangeEnd: net.ParseIP("192.0.2.40"),
|
||||||
}
|
}
|
||||||
@ -99,8 +128,9 @@ var _ = Describe("IP ranges", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should parse all fields correctly", func() {
|
It("should parse all fields correctly", func() {
|
||||||
|
snstr := "192.0.2.0/24"
|
||||||
r := Range{
|
r := Range{
|
||||||
Subnet: mustSubnet("192.0.2.0/24"),
|
Subnet: mustSubnet(snstr),
|
||||||
RangeStart: net.ParseIP("192.0.2.40"),
|
RangeStart: net.ParseIP("192.0.2.40"),
|
||||||
RangeEnd: net.ParseIP("192.0.2.50"),
|
RangeEnd: net.ParseIP("192.0.2.50"),
|
||||||
Gateway: net.ParseIP("192.0.2.254"),
|
Gateway: net.ParseIP("192.0.2.254"),
|
||||||
@ -109,7 +139,7 @@ var _ = Describe("IP ranges", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
Expect(r).To(Equal(Range{
|
Expect(r).To(Equal(Range{
|
||||||
Subnet: mustSubnet("192.0.2.0/24"),
|
Subnet: networkSubnet(snstr),
|
||||||
RangeStart: net.IP{192, 0, 2, 40},
|
RangeStart: net.IP{192, 0, 2, 40},
|
||||||
RangeEnd: net.IP{192, 0, 2, 50},
|
RangeEnd: net.IP{192, 0, 2, 50},
|
||||||
Gateway: net.IP{192, 0, 2, 254},
|
Gateway: net.IP{192, 0, 2, 254},
|
||||||
@ -207,3 +237,9 @@ func mustSubnet(s string) types.IPNet {
|
|||||||
canonicalizeIP(&n.IP)
|
canonicalizeIP(&n.IP)
|
||||||
return types.IPNet(*n)
|
return types.IPNet(*n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func networkSubnet(s string) types.IPNet {
|
||||||
|
net := mustSubnet(s)
|
||||||
|
net.IP = net.IP.Mask(net.Mask)
|
||||||
|
return net
|
||||||
|
}
|
||||||
|
@ -444,7 +444,7 @@ var _ = Describe("host-local Operations", func() {
|
|||||||
"dataDir": "%s",
|
"dataDir": "%s",
|
||||||
"ranges": [
|
"ranges": [
|
||||||
[{"subnet":"172.16.1.0/24"}, { "subnet": "10.1.2.0/24" }],
|
[{"subnet":"172.16.1.0/24"}, { "subnet": "10.1.2.0/24" }],
|
||||||
[{ "subnet": "2001:db8:1::/24" }]
|
[{ "subnet": "2001:db8:1::/48" }]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"args": {
|
"args": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user