Compare commits
No commits in common. "0618b41ae2aba36241c9a4219fbdb2e3a169d780" and "88ad00ae93dfcbba2bbe15d4ba450bac5a1302ec" have entirely different histories.
0618b41ae2
...
88ad00ae93
136
main.go
136
main.go
@ -1,8 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
@ -16,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PluginName = "mycelium-cni"
|
PluginName = "mycelium-cni"
|
||||||
MyceliumInterface = "mycelium"
|
MyceliumInterface = "mycelium"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,8 +46,8 @@ func cmdAdd(args *skel.CmdArgs) error {
|
|||||||
return fmt.Errorf("failed to get Mycelium IP: %v", err)
|
return fmt.Errorf("failed to get Mycelium IP: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create veth pair with unique naming
|
// Create veth pair
|
||||||
hostVethName := generateVethName(args.ContainerID)
|
hostVethName := fmt.Sprintf("veth-%s", args.ContainerID[:8])
|
||||||
containerVethName := "eth0"
|
containerVethName := "eth0"
|
||||||
|
|
||||||
hostVeth, containerVeth, err := createVethPair(hostVethName, containerVethName)
|
hostVeth, containerVeth, err := createVethPair(hostVethName, containerVethName)
|
||||||
@ -103,8 +101,8 @@ func cmdCheck(args *skel.CmdArgs) error {
|
|||||||
|
|
||||||
func cmdDel(args *skel.CmdArgs) error {
|
func cmdDel(args *skel.CmdArgs) error {
|
||||||
// Clean up veth pair (host side will be automatically removed)
|
// Clean up veth pair (host side will be automatically removed)
|
||||||
hostVethName := generateVethName(args.ContainerID)
|
hostVethName := fmt.Sprintf("veth-%s", args.ContainerID[:8])
|
||||||
|
|
||||||
link, err := netlink.LinkByName(hostVethName)
|
link, err := netlink.LinkByName(hostVethName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Interface might already be gone, which is fine
|
// Interface might already be gone, which is fine
|
||||||
@ -148,25 +146,14 @@ func getMyceliumIP(interfaceName string) (net.IP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateContainerIP(myceliumPrefix net.IP, containerID string) net.IP {
|
func generateContainerIP(myceliumPrefix net.IP, containerID string) net.IP {
|
||||||
// Generate a unique container IP within the /64 prefix using container ID hash
|
// Generate a container IP within the /64 prefix
|
||||||
hash := sha256.Sum256([]byte(containerID))
|
// Using simple approach: prefix + ::1 (could be made more sophisticated)
|
||||||
|
|
||||||
containerIP := make(net.IP, len(myceliumPrefix))
|
containerIP := make(net.IP, len(myceliumPrefix))
|
||||||
copy(containerIP, myceliumPrefix)
|
copy(containerIP, myceliumPrefix)
|
||||||
|
containerIP[15] = 1 // Set last byte to 1
|
||||||
// Use first 8 bytes of hash for the host part (last 64 bits)
|
|
||||||
copy(containerIP[8:], hash[:8])
|
|
||||||
|
|
||||||
return containerIP
|
return containerIP
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateVethName(containerID string) string {
|
|
||||||
// Generate unique but short veth name using hash of container ID
|
|
||||||
hash := sha256.Sum256([]byte(containerID))
|
|
||||||
shortHash := hex.EncodeToString(hash[:4]) // Use first 4 bytes for 8-char hex
|
|
||||||
return fmt.Sprintf("veth-%s", shortHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createVethPair(hostName, containerName string) (netlink.Link, netlink.Link, error) {
|
func createVethPair(hostName, containerName string) (netlink.Link, netlink.Link, error) {
|
||||||
veth := &netlink.Veth{
|
veth := &netlink.Veth{
|
||||||
LinkAttrs: netlink.LinkAttrs{Name: hostName},
|
LinkAttrs: netlink.LinkAttrs{Name: hostName},
|
||||||
@ -207,73 +194,52 @@ func configureContainerInterface(containerNS netns.NsHandle, ifName string, cont
|
|||||||
if err := netns.Set(containerNS); err != nil {
|
if err := netns.Set(containerNS); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Get the interface
|
// Get the interface
|
||||||
link, err := netlink.LinkByName(ifName)
|
link, err := netlink.LinkByName(ifName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bring interface up
|
|
||||||
if err := netlink.LinkSetUp(link); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add IP address
|
|
||||||
addr := &netlink.Addr{
|
|
||||||
IPNet: &net.IPNet{
|
|
||||||
IP: containerIP,
|
|
||||||
Mask: net.CIDRMask(64, 128),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := netlink.AddrAdd(link, addr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to main namespace to get host veth address
|
|
||||||
if err := netns.Set(originalNS); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get host veth link-local address
|
|
||||||
hostVeth, err := netlink.LinkByName(hostVethName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
hostAddrs, err := netlink.AddrList(hostVeth, netlink.FAMILY_V6)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var hostLLAddr net.IP
|
|
||||||
for _, addr := range hostAddrs {
|
|
||||||
if addr.IP.IsLinkLocalUnicast() {
|
|
||||||
hostLLAddr = addr.IP
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch back to container namespace to add route
|
|
||||||
if err := netns.Set(containerNS); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if hostLLAddr != nil {
|
|
||||||
// Add route to Mycelium network via host veth
|
|
||||||
route := &netlink.Route{
|
|
||||||
Dst: &net.IPNet{
|
|
||||||
IP: net.ParseIP("400::"),
|
|
||||||
Mask: net.CIDRMask(7, 128),
|
|
||||||
},
|
|
||||||
Gw: hostLLAddr,
|
|
||||||
LinkIndex: link.Attrs().Index,
|
|
||||||
}
|
|
||||||
if err := netlink.RouteAdd(route); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
// Bring interface up
|
||||||
|
if err := netlink.LinkSetUp(link); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add IP address
|
||||||
|
addr := &netlink.Addr{
|
||||||
|
IPNet: &net.IPNet{
|
||||||
|
IP: containerIP,
|
||||||
|
Mask: net.CIDRMask(64, 128),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := netlink.AddrAdd(link, addr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get host veth link-local address for routing
|
||||||
|
hostVeth, err := netlink.LinkByName(hostVethName)
|
||||||
|
if err == nil {
|
||||||
|
hostAddrs, err := netlink.AddrList(hostVeth, netlink.FAMILY_V6)
|
||||||
|
if err == nil {
|
||||||
|
for _, addr := range hostAddrs {
|
||||||
|
if addr.IP.IsLinkLocalUnicast() {
|
||||||
|
// Add route to Mycelium network via host veth
|
||||||
|
route := &netlink.Route{
|
||||||
|
Dst: &net.IPNet{
|
||||||
|
IP: net.ParseIP("400::"),
|
||||||
|
Mask: net.CIDRMask(7, 128),
|
||||||
|
},
|
||||||
|
Gw: addr.IP,
|
||||||
|
LinkIndex: link.Attrs().Index,
|
||||||
|
}
|
||||||
|
netlink.RouteAdd(route)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureHostInterface(hostVeth netlink.Link, containerIP net.IP) error {
|
func configureHostInterface(hostVeth netlink.Link, containerIP net.IP) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user