github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/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/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 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 if err := nlh.LinkAdd(veth); err != nil { 53 return "", "", fmt.Errorf("error creating veth pair: %v", err) 54 } 55 56 return name1, name2, nil 57 } 58 59 func createVxlan(name string, vni uint32, mtu int) error { 60 vxlan := &netlink.Vxlan{ 61 LinkAttrs: netlink.LinkAttrs{Name: name, MTU: mtu}, 62 VxlanId: int(vni), 63 Learning: true, 64 Port: int(overlayutils.VXLANUDPPort()), 65 Proxy: true, 66 L3miss: true, 67 L2miss: true, 68 } 69 70 if err := ns.NlHandle().LinkAdd(vxlan); err != nil { 71 return fmt.Errorf("error creating vxlan interface: %v", err) 72 } 73 74 return nil 75 } 76 77 func deleteInterfaceBySubnet(brPrefix string, s *subnet) error { 78 nlh := ns.NlHandle() 79 links, err := nlh.LinkList() 80 if err != nil { 81 return fmt.Errorf("failed to list interfaces while deleting bridge interface by subnet: %v", err) 82 } 83 84 for _, l := range links { 85 name := l.Attrs().Name 86 if _, ok := l.(*netlink.Bridge); ok && strings.HasPrefix(name, brPrefix) { 87 addrList, err := nlh.AddrList(l, netlink.FAMILY_V4) 88 if err != nil { 89 logrus.Errorf("error getting AddressList for bridge %s", name) 90 continue 91 } 92 for _, addr := range addrList { 93 if netutils.NetworkOverlaps(addr.IPNet, s.subnetIP) { 94 err = nlh.LinkDel(l) 95 if err != nil { 96 logrus.Errorf("error deleting bridge (%s) with subnet %v: %v", name, addr.IPNet, err) 97 } 98 } 99 } 100 } 101 } 102 return nil 103 } 104 105 func deleteInterface(name string) error { 106 link, err := ns.NlHandle().LinkByName(name) 107 if err != nil { 108 return fmt.Errorf("failed to find interface with name %s: %v", name, err) 109 } 110 111 if err := ns.NlHandle().LinkDel(link); err != nil { 112 return fmt.Errorf("error deleting interface with name %s: %v", name, err) 113 } 114 115 return nil 116 } 117 118 func deleteVxlanByVNI(path string, vni uint32) error { 119 nlh := ns.NlHandle() 120 if path != "" { 121 ns, err := netns.GetFromPath(path) 122 if err != nil { 123 return fmt.Errorf("failed to get ns handle for %s: %v", path, err) 124 } 125 defer ns.Close() 126 127 nlh, err = netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE) 128 if err != nil { 129 return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err) 130 } 131 defer nlh.Close() 132 err = nlh.SetSocketTimeout(soTimeout) 133 if err != nil { 134 logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err) 135 } 136 } 137 138 links, err := nlh.LinkList() 139 if err != nil { 140 return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err) 141 } 142 143 for _, l := range links { 144 if l.Type() == "vxlan" && (vni == 0 || l.(*netlink.Vxlan).VxlanId == int(vni)) { 145 err = nlh.LinkDel(l) 146 if err != nil { 147 return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err) 148 } 149 return nil 150 } 151 } 152 153 return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni) 154 }