github.com/rish1988/moby@v25.0.2+incompatible/libnetwork/drivers/overlay/ov_utils.go (about) 1 //go:build linux 2 3 package overlay 4 5 import ( 6 "context" 7 "fmt" 8 "net" 9 "syscall" 10 11 "github.com/containerd/log" 12 "github.com/docker/docker/libnetwork/drivers/overlay/overlayutils" 13 "github.com/docker/docker/libnetwork/netutils" 14 "github.com/docker/docker/libnetwork/ns" 15 "github.com/vishvananda/netlink" 16 "github.com/vishvananda/netns" 17 ) 18 19 var soTimeout = ns.NetlinkSocketsTimeout 20 21 func validateID(nid, eid string) error { 22 if nid == "" { 23 return fmt.Errorf("invalid network id") 24 } 25 26 if eid == "" { 27 return fmt.Errorf("invalid endpoint id") 28 } 29 30 return nil 31 } 32 33 func createVethPair() (string, string, error) { 34 nlh := ns.NlHandle() 35 36 // Generate a name for what will be the host side pipe interface 37 name1, err := netutils.GenerateIfaceName(nlh, vethPrefix, vethLen) 38 if err != nil { 39 return "", "", fmt.Errorf("error generating veth name1: %v", err) 40 } 41 42 // Generate a name for what will be the sandbox side pipe interface 43 name2, err := netutils.GenerateIfaceName(nlh, vethPrefix, vethLen) 44 if err != nil { 45 return "", "", fmt.Errorf("error generating veth name2: %v", err) 46 } 47 48 // Generate and add the interface pipe host <-> sandbox 49 veth := &netlink.Veth{ 50 LinkAttrs: netlink.LinkAttrs{Name: name1, TxQLen: 0}, 51 PeerName: name2, 52 } 53 if err := nlh.LinkAdd(veth); err != nil { 54 return "", "", fmt.Errorf("error creating veth pair: %v", err) 55 } 56 57 return name1, name2, nil 58 } 59 60 func createVxlan(name string, vni uint32, mtu int, vtepIPv6 bool) error { 61 vxlan := &netlink.Vxlan{ 62 LinkAttrs: netlink.LinkAttrs{Name: name, MTU: mtu}, 63 VxlanId: int(vni), 64 Learning: true, 65 Port: int(overlayutils.VXLANUDPPort()), 66 Proxy: true, 67 L3miss: true, 68 L2miss: true, 69 } 70 71 // The kernel restricts the destination VTEP (virtual tunnel endpoint) in 72 // VXLAN forwarding database entries to a single address family, defaulting 73 // to IPv4 unless either an IPv6 group or default remote destination address 74 // is configured when the VXLAN link is created. 75 // 76 // Set up the VXLAN link for IPv6 destination addresses by setting the VXLAN 77 // group address to the IPv6 unspecified address, like iproute2. 78 // https://github.com/iproute2/iproute2/commit/97d564b90ccb1e4a3c756d9caae161f55b2b63a2 79 // https://patchwork.ozlabs.org/project/netdev/patch/20180917171325.GA2660@localhost.localdomain/ 80 if vtepIPv6 { 81 vxlan.Group = net.IPv6unspecified 82 } 83 84 if err := ns.NlHandle().LinkAdd(vxlan); err != nil { 85 return fmt.Errorf("error creating vxlan interface: %v", err) 86 } 87 88 return nil 89 } 90 91 func deleteInterface(name string) error { 92 link, err := ns.NlHandle().LinkByName(name) 93 if err != nil { 94 return fmt.Errorf("failed to find interface with name %s: %v", name, err) 95 } 96 97 if err := ns.NlHandle().LinkDel(link); err != nil { 98 return fmt.Errorf("error deleting interface with name %s: %v", name, err) 99 } 100 101 return nil 102 } 103 104 func deleteVxlanByVNI(path string, vni uint32) error { 105 nlh := ns.NlHandle() 106 if path != "" { 107 ns, err := netns.GetFromPath(path) 108 if err != nil { 109 return fmt.Errorf("failed to get ns handle for %s: %v", path, err) 110 } 111 defer ns.Close() 112 113 nlh, err = netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE) 114 if err != nil { 115 return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err) 116 } 117 defer nlh.Close() 118 err = nlh.SetSocketTimeout(soTimeout) 119 if err != nil { 120 log.G(context.TODO()).Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err) 121 } 122 } 123 124 links, err := nlh.LinkList() 125 if err != nil { 126 return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err) 127 } 128 129 for _, l := range links { 130 if l.Type() == "vxlan" && (vni == 0 || l.(*netlink.Vxlan).VxlanId == int(vni)) { 131 err = nlh.LinkDel(l) 132 if err != nil { 133 return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err) 134 } 135 return nil 136 } 137 } 138 139 return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni) 140 }