VRF CNI: Add an optional table parameter.

When specified from the user, the VRF will get assigned to the given
tableid instead of having the CNI to choose for a free one.

Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
This commit is contained in:
Federico Paolinelli
2020-09-18 11:27:46 +02:00
parent ccd872bd7a
commit b34402abd3
4 changed files with 107 additions and 7 deletions

View File

@ -354,6 +354,69 @@ var _ = Describe("vrf plugin", func() {
Entry("added to different vrfs with same ip IPV6", VRF0Name, VRF1Name, "2A00:0C98:2060:A000:0001:0000:1d1e:ca75/64", "2A00:0C98:2060:A000:0001:0000:1d1e:ca75/64"),
)
DescribeTable("handles tableid conflicts",
func(vrf0, vrf1 string, tableid0, tableid1 int, expectedError string) {
conf0 := configWithTableFor("test", IF0Name, vrf0, "10.0.0.2/24", tableid0)
conf1 := configWithTableFor("test1", IF1Name, vrf1, "10.0.0.2/24", tableid1)
By("Adding the first interface to first vrf", func() {
err := originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNS.Path(),
IfName: IF0Name,
StdinData: conf0,
}
_, _, err := testutils.CmdAddWithArgs(args, func() error {
return cmdAdd(args)
})
Expect(err).NotTo(HaveOccurred())
return nil
})
Expect(err).NotTo(HaveOccurred())
})
By("Checking that the first vrf has the right routing table", func() {
err := targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
l, err := netlink.LinkByName(vrf0)
Expect(err).NotTo(HaveOccurred())
vrf := l.(*netlink.Vrf)
Expect(vrf.Table).To(Equal(uint32(tableid0)))
return nil
})
Expect(err).NotTo(HaveOccurred())
})
By("Adding the second interface to second vrf", func() {
err := originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNS.Path(),
IfName: IF1Name,
StdinData: conf1,
}
_, _, err := testutils.CmdAddWithArgs(args, func() error {
return cmdAdd(args)
})
return err
})
if expectedError != "" {
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring(expectedError))
return
}
Expect(err).NotTo(HaveOccurred())
})
},
Entry("same vrf with same tableid", VRF0Name, VRF0Name, 1001, 1001, ""),
Entry("different vrf with same tableid", VRF0Name, VRF1Name, 1001, 1001, ""),
Entry("same vrf with different tableids", VRF0Name, VRF0Name, 1001, 1002, "already exist with different routing table"),
)
It("removes the VRF only when the last interface is removed", func() {
conf0 := configFor("test", IF0Name, VRF0Name, "10.0.0.2/24")
conf1 := configFor("test1", IF1Name, VRF0Name, "10.0.0.2/24")
@ -605,6 +668,30 @@ func configFor(name, intf, vrf, ip string) []byte {
return []byte(conf)
}
func configWithTableFor(name, intf, vrf, ip string, tableID int) []byte {
conf := fmt.Sprintf(`{
"name": "%s",
"type": "vrf",
"cniVersion": "0.3.1",
"vrfName": "%s",
"table": %d,
"prevResult": {
"interfaces": [
{"name": "%s", "sandbox":"netns"}
],
"ips": [
{
"version": "4",
"address": "%s",
"gateway": "10.0.0.1",
"interface": 0
}
]
}
}`, name, vrf, tableID, intf, ip)
return []byte(conf)
}
func checkInterfaceOnVRF(vrfName, intfName string) {
vrf, err := netlink.LinkByName(vrfName)
Expect(err).NotTo(HaveOccurred())