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  }