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