// Join joins to network namespace
func (n *Namespace) Join() error {
	runtime.LockOSThread()
	f, err := os.OpenFile(n.Path, os.O_RDONLY, 0)
	if err != nil {
		return fmt.Errorf("failed get network namespace fd: %v", err)
	}
	defer f.Close()
	if _, _, err := syscall.RawSyscall(syscall.SYS_SETNS, f.Fd(), syscall.CLONE_NEWNET, 0); err != 0 {
		return err
	}
	return nil
}
Beispiel #2
0
func main() {
	if len(os.Args) != 3 {
		panic("not enough args")
	}

	intf, err := net.InterfaceByName(os.Args[1])
	if err != nil {
		panic(err)
	}

	containerID := os.Args[2]

	log.Infof("Requesting for container ID %q on interface %q", containerID, intf.Name)

	contPid := getContainerInfo(containerID)
	log.Infof("Container has PID %s", contPid)

	runtime.LockOSThread()
	f, err := os.Open(fmt.Sprintf("/proc/%s/ns/net", contPid))
	if err != nil {
		panic(err)
	}

	if _, _, err := unix.RawSyscall(unix.SYS_SETNS, f.Fd(), syscall.CLONE_NEWNET, 0); err != 0 {
		panic(err)
	}

	link, err := netlink.LinkByName("eth0")
	if err != nil {
		panic(err)
	}

	chaddr := link.Attrs().HardwareAddr

	p := dhcp.RequestPacket(dhcp.Discover, chaddr, nil, []byte{1, 2, 3, 4}, true, []dhcp.Option{})
	conn, err := net.ListenPacket("udp", ":68")
	if err != nil {
		panic(err)
	}

	ipc := ipv4.NewPacketConn(conn)
	ipc.SetControlMessage(ipv4.FlagInterface, true)
	to := &net.UDPAddr{
		IP:   net.IPv4(255, 255, 255, 255),
		Port: 67,
	}

	eth0, err := net.InterfaceByName("eth0")
	if err != nil {
		panic(err)
	}

	if _, err := ipc.WriteTo(p, &ipv4.ControlMessage{IfIndex: eth0.Index}, to); err != nil {
		panic(err)
	}

	newPacket := dhcp.NewPacket(dhcp.BootReply)

	for {
		_, cm, _, err := ipc.ReadFrom(newPacket)
		if err != nil {
			panic(err)
		}

		if cm != nil && cm.IfIndex == eth0.Index {
			log.Infof("Received reply: %q", newPacket.YIAddr().String())
			break
		}
	}

	addr, err := netlink.ParseAddr(newPacket.YIAddr().String() + "/16")
	if err != nil {
		panic(err)
	}

	log.Infof("Setting interface eth0...")

	if err := netlink.AddrAdd(link, addr); err != nil {
		panic(err)
	}
}