update route handling
This commit is contained in:
parent
88ad00ae93
commit
454fe42546
73
main.go
73
main.go
@ -3,7 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/skel"
|
"github.com/containernetworking/cni/pkg/skel"
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
@ -60,9 +62,15 @@ func cmdAdd(args *skel.CmdArgs) error {
|
|||||||
return fmt.Errorf("failed to move veth to container netns: %v", err)
|
return fmt.Errorf("failed to move veth to container netns: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get host veth link-local address with retry
|
||||||
|
hostLinkLocal, err := getHostVethLinkLocalWithRetry(hostVeth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get host veth link-local address: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Configure container interface
|
// Configure container interface
|
||||||
containerIP := generateContainerIP(myceliumIP, args.ContainerID)
|
containerIP := generateContainerIP(myceliumIP, args.ContainerID)
|
||||||
if err := configureContainerInterface(containerNS, containerVethName, containerIP, hostVethName); err != nil {
|
if err := configureContainerInterface(containerNS, containerVethName, containerIP, hostLinkLocal); err != nil {
|
||||||
return fmt.Errorf("failed to configure container interface: %v", err)
|
return fmt.Errorf("failed to configure container interface: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +190,7 @@ func createVethPair(hostName, containerName string) (netlink.Link, netlink.Link,
|
|||||||
return hostVeth, containerVeth, nil
|
return hostVeth, containerVeth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureContainerInterface(containerNS netns.NsHandle, ifName string, containerIP net.IP, hostVethName string) error {
|
func configureContainerInterface(containerNS netns.NsHandle, ifName string, containerIP net.IP, hostLinkLocal net.IP) error {
|
||||||
// Switch to container namespace
|
// Switch to container namespace
|
||||||
originalNS, err := netns.Get()
|
originalNS, err := netns.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -216,27 +224,17 @@ func configureContainerInterface(containerNS netns.NsHandle, ifName string, cont
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get host veth link-local address for routing
|
// Add route to Mycelium network via host veth link-local address
|
||||||
hostVeth, err := netlink.LinkByName(hostVethName)
|
route := &netlink.Route{
|
||||||
if err == nil {
|
Dst: &net.IPNet{
|
||||||
hostAddrs, err := netlink.AddrList(hostVeth, netlink.FAMILY_V6)
|
IP: net.ParseIP("400::"),
|
||||||
if err == nil {
|
Mask: net.CIDRMask(7, 128),
|
||||||
for _, addr := range hostAddrs {
|
},
|
||||||
if addr.IP.IsLinkLocalUnicast() {
|
Gw: hostLinkLocal,
|
||||||
// Add route to Mycelium network via host veth
|
LinkIndex: link.Attrs().Index,
|
||||||
route := &netlink.Route{
|
}
|
||||||
Dst: &net.IPNet{
|
if err := netlink.RouteAdd(route); err != nil {
|
||||||
IP: net.ParseIP("400::"),
|
return fmt.Errorf("failed to add route to 400::/7: %v", err)
|
||||||
Mask: net.CIDRMask(7, 128),
|
|
||||||
},
|
|
||||||
Gw: addr.IP,
|
|
||||||
LinkIndex: link.Attrs().Index,
|
|
||||||
}
|
|
||||||
netlink.RouteAdd(route)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -254,3 +252,32 @@ func configureHostInterface(hostVeth netlink.Link, containerIP net.IP) error {
|
|||||||
|
|
||||||
return netlink.RouteAdd(route)
|
return netlink.RouteAdd(route)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getHostVethLinkLocal(hostVeth netlink.Link) (net.IP, error) {
|
||||||
|
addrs, err := netlink.AddrList(hostVeth, netlink.FAMILY_V6)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get addresses for host veth: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("DEBUG: Interface %s has %d IPv6 addresses", hostVeth.Attrs().Name, len(addrs))
|
||||||
|
for i, addr := range addrs {
|
||||||
|
log.Printf("DEBUG: Address %d: %s, IsLinkLocalUnicast: %v", i, addr.IP.String(), addr.IP.IsLinkLocalUnicast())
|
||||||
|
if addr.IP.IsLinkLocalUnicast() {
|
||||||
|
return addr.IP, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("no link-local address found on host veth %s", hostVeth.Attrs().Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHostVethLinkLocalWithRetry(hostVeth netlink.Link) (net.IP, error) {
|
||||||
|
// Retry for up to 5 seconds, checking every 100ms
|
||||||
|
for i := 0; i < 50; i++ {
|
||||||
|
ip, err := getHostVethLinkLocal(hostVeth)
|
||||||
|
if err == nil {
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("timeout waiting for host veth link-local address")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user