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