github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/libnetwork/drivers/overlay/ov_utils.go (about) 1 //go:build linux 2 // +build linux 3 4 package overlay 5 6 import ( 7 "fmt" 8 "strings" 9 "syscall" 10 11 "github.com/docker/docker/libnetwork/drivers/overlay/overlayutils" 12 "github.com/docker/docker/libnetwork/netutils" 13 "github.com/docker/docker/libnetwork/ns" 14 "github.com/docker/docker/libnetwork/osl" 15 "github.com/sirupsen/logrus" 16 "github.com/vishvananda/netlink" 17 "github.com/vishvananda/netns" 18 ) 19 20 var soTimeout = ns.NetlinkSocketsTimeout 21 22 func validateID(nid, eid string) error { 23 if nid == "" { 24 return fmt.Errorf("invalid network id") 25 } 26 27 if eid == "" { 28 return fmt.Errorf("invalid endpoint id") 29 } 30 31 return nil 32 } 33 34 func createVethPair() (string, string, error) { 35 defer osl.InitOSContext()() 36 nlh := ns.NlHandle() 37 38 // Generate a name for what will be the host side pipe interface 39 name1, err := netutils.GenerateIfaceName(nlh, vethPrefix, vethLen) 40 if err != nil { 41 return "", "", fmt.Errorf("error generating veth name1: %v", err) 42 } 43 44 // Generate a name for what will be the sandbox side pipe interface 45 name2, err := netutils.GenerateIfaceName(nlh, vethPrefix, vethLen) 46 if err != nil { 47 return "", "", fmt.Errorf("error generating veth name2: %v", err) 48 } 49 50 // Generate and add the interface pipe host <-> sandbox 51 veth := &netlink.Veth{ 52 LinkAttrs: netlink.LinkAttrs{Name: name1, TxQLen: 0}, 53 PeerName: name2} 54 if err := nlh.LinkAdd(veth); err != nil { 55 return "", "", fmt.Errorf("error creating veth pair: %v", err) 56 } 57 58 return name1, name2, nil 59 } 60 61 func createVxlan(name string, vni uint32, mtu int) error { 62 defer osl.InitOSContext()() 63 64 vxlan := &netlink.Vxlan{ 65 LinkAttrs: netlink.LinkAttrs{Name: name, MTU: mtu}, 66 VxlanId: int(vni), 67 Learning: true, 68 Port: int(overlayutils.VXLANUDPPort()), 69 Proxy: true, 70 L3miss: true, 71 L2miss: true, 72 } 73 74 if err := ns.NlHandle().LinkAdd(vxlan); err != nil { 75 return fmt.Errorf("error creating vxlan interface: %v", err) 76 } 77 78 return nil 79 } 80 81 func deleteInterfaceBySubnet(brPrefix string, s *subnet) error { 82 defer osl.InitOSContext()() 83 84 nlh := ns.NlHandle() 85 links, err := nlh.LinkList() 86 if err != nil { 87 return fmt.Errorf("failed to list interfaces while deleting bridge interface by subnet: %v", err) 88 } 89 90 for _, l := range links { 91 name := l.Attrs().Name 92 if _, ok := l.(*netlink.Bridge); ok && strings.HasPrefix(name, brPrefix) { 93 addrList, err := nlh.AddrList(l, netlink.FAMILY_V4) 94 if err != nil { 95 logrus.Errorf("error getting AddressList for bridge %s", name) 96 continue 97 } 98 for _, addr := range addrList { 99 if netutils.NetworkOverlaps(addr.IPNet, s.subnetIP) { 100 err = nlh.LinkDel(l) 101 if err != nil { 102 logrus.Errorf("error deleting bridge (%s) with subnet %v: %v", name, addr.IPNet, err) 103 } 104 } 105 } 106 } 107 } 108 return nil 109 110 } 111 112 func deleteInterface(name string) error { 113 defer osl.InitOSContext()() 114 115 link, err := ns.NlHandle().LinkByName(name) 116 if err != nil { 117 return fmt.Errorf("failed to find interface with name %s: %v", name, err) 118 } 119 120 if err := ns.NlHandle().LinkDel(link); err != nil { 121 return fmt.Errorf("error deleting interface with name %s: %v", name, err) 122 } 123 124 return nil 125 } 126 127 func deleteVxlanByVNI(path string, vni uint32) error { 128 defer osl.InitOSContext()() 129 130 nlh := ns.NlHandle() 131 if path != "" { 132 ns, err := netns.GetFromPath(path) 133 if err != nil { 134 return fmt.Errorf("failed to get ns handle for %s: %v", path, err) 135 } 136 defer ns.Close() 137 138 nlh, err = netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE) 139 if err != nil { 140 return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err) 141 } 142 defer nlh.Delete() 143 err = nlh.SetSocketTimeout(soTimeout) 144 if err != nil { 145 logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err) 146 } 147 } 148 149 links, err := nlh.LinkList() 150 if err != nil { 151 return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err) 152 } 153 154 for _, l := range links { 155 if l.Type() == "vxlan" && (vni == 0 || l.(*netlink.Vxlan).VxlanId == int(vni)) { 156 err = nlh.LinkDel(l) 157 if err != nil { 158 return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err) 159 } 160 return nil 161 } 162 } 163 164 return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni) 165 }