| 53 | } |
| 54 | |
| 55 | func (v *Veth) BindContainer(gatewayIP string, addr *net.IPNet) error { |
| 56 | logs.Infof("start bind container(pid: %d) with veth(ip: %s)", v.ContainerPID, addr.IP.String()) |
| 57 | |
| 58 | // Get the peer link. |
| 59 | peer, err := netlink.LinkByName(v.vethPair.PeerName) |
| 60 | if err != nil { |
| 61 | return fmt.Errorf("getting peer interface %s failed: %v", v.vethPair.PeerName, err) |
| 62 | } |
| 63 | |
| 64 | // Put peer interface into the network namespace of specified PID. |
| 65 | if err := netlink.LinkSetNsPid(peer, v.ContainerPID); err != nil { |
| 66 | return fmt.Errorf("adding peer interface to network namespace of pid %d failed: %v", v.ContainerPID, err) |
| 67 | } |
| 68 | |
| 69 | // Bring the veth pair up. |
| 70 | if err := netlink.LinkSetUp(v.vethPair); err != nil { |
| 71 | return fmt.Errorf("bringing local veth pair [ %#v ] up failed: %v", peer, err) |
| 72 | } |
| 73 | |
| 74 | // Lock the OS Thread so we don't accidentally switch namespaces. |
| 75 | runtime.LockOSThread() |
| 76 | defer runtime.UnlockOSThread() |
| 77 | |
| 78 | origns, err := netns.Get() |
| 79 | if err != nil { |
| 80 | return fmt.Errorf("getting current network namespace failed: %v", err) |
| 81 | } |
| 82 | defer origns.Close() |
| 83 | |
| 84 | newns, err := netns.GetFromPid(v.ContainerPID) |
| 85 | if err != nil { |
| 86 | return fmt.Errorf("getting network namespace for pid %d failed: %v", v.ContainerPID, err) |
| 87 | } |
| 88 | defer newns.Close() |
| 89 | |
| 90 | if err := netns.Set(newns); err != nil { |
| 91 | return fmt.Errorf("entering network namespace failed: %v", err) |
| 92 | } |
| 93 | |
| 94 | if err := netlink.LinkSetDown(peer); err != nil { |
| 95 | return fmt.Errorf("bringing interface [ %#v ] down failed: %v", peer, err) |
| 96 | } |
| 97 | |
| 98 | if err := netlink.LinkSetName(peer, "eth0"); err != nil { |
| 99 | return fmt.Errorf("renaming interface %s to %s failed: %v", v.vethPair.PeerName, "eth0", err) |
| 100 | } |
| 101 | |
| 102 | // Add the IP address. |
| 103 | ipAddr := &netlink.Addr{IPNet: addr, Label: ""} |
| 104 | if err := netlink.AddrAdd(peer, ipAddr); err != nil { |
| 105 | return fmt.Errorf("setting %s interface ip to %s failed: %v", v.vethPair.PeerName, addr.String(), err) |
| 106 | } |
| 107 | |
| 108 | if err := netlink.LinkSetUp(peer); err != nil { |
| 109 | return fmt.Errorf("bringing interface [ %#v ] up failed: %v", peer, err) |
| 110 | } |
| 111 | |
| 112 | gw := net.ParseIP(gatewayIP) |