Compare commits
	
		
			2 Commits
		
	
	
		
			88ad00ae93
			...
			0618b41ae2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 0618b41ae2 | ||
|  | 9bdaf13797 | 
							
								
								
									
										128
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								main.go
									
									
									
									
									
								
							| @@ -1,6 +1,8 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/hex" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| @@ -14,7 +16,7 @@ import ( | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	PluginName = "mycelium-cni" | ||||
| 	PluginName        = "mycelium-cni" | ||||
| 	MyceliumInterface = "mycelium" | ||||
| ) | ||||
|  | ||||
| @@ -46,8 +48,8 @@ func cmdAdd(args *skel.CmdArgs) error { | ||||
| 		return fmt.Errorf("failed to get Mycelium IP: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Create veth pair | ||||
| 	hostVethName := fmt.Sprintf("veth-%s", args.ContainerID[:8]) | ||||
| 	// Create veth pair with unique naming | ||||
| 	hostVethName := generateVethName(args.ContainerID) | ||||
| 	containerVethName := "eth0" | ||||
|  | ||||
| 	hostVeth, containerVeth, err := createVethPair(hostVethName, containerVethName) | ||||
| @@ -101,8 +103,8 @@ func cmdCheck(args *skel.CmdArgs) error { | ||||
|  | ||||
| func cmdDel(args *skel.CmdArgs) error { | ||||
| 	// Clean up veth pair (host side will be automatically removed) | ||||
| 	hostVethName := fmt.Sprintf("veth-%s", args.ContainerID[:8]) | ||||
| 	 | ||||
| 	hostVethName := generateVethName(args.ContainerID) | ||||
|  | ||||
| 	link, err := netlink.LinkByName(hostVethName) | ||||
| 	if err != nil { | ||||
| 		// Interface might already be gone, which is fine | ||||
| @@ -146,14 +148,25 @@ func getMyceliumIP(interfaceName string) (net.IP, error) { | ||||
| } | ||||
|  | ||||
| func generateContainerIP(myceliumPrefix net.IP, containerID string) net.IP { | ||||
| 	// Generate a container IP within the /64 prefix | ||||
| 	// Using simple approach: prefix + ::1 (could be made more sophisticated) | ||||
| 	// Generate a unique container IP within the /64 prefix using container ID hash | ||||
| 	hash := sha256.Sum256([]byte(containerID)) | ||||
| 	 | ||||
| 	containerIP := make(net.IP, len(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 | ||||
| } | ||||
|  | ||||
| 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) { | ||||
| 	veth := &netlink.Veth{ | ||||
| 		LinkAttrs: netlink.LinkAttrs{Name: hostName}, | ||||
| @@ -194,52 +207,73 @@ func configureContainerInterface(containerNS netns.NsHandle, ifName string, cont | ||||
| 	if err := netns.Set(containerNS); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 		// Get the interface | ||||
| 		link, err := netlink.LinkByName(ifName) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	// Get the interface | ||||
| 	link, err := netlink.LinkByName(ifName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 		// Bring interface up | ||||
| 		if err := netlink.LinkSetUp(link); 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), | ||||
| 	// 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.AddrAdd(link, addr); err != nil { | ||||
| 		if err := netlink.RouteAdd(route); 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 | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func configureHostInterface(hostVeth netlink.Link, containerIP net.IP) error { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user