github.com/rish1988/moby@v25.0.2+incompatible/libnetwork/drivers/overlay/ov_utils.go (about)

     1  //go:build linux
     2  
     3  package overlay
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"net"
     9  	"syscall"
    10  
    11  	"github.com/containerd/log"
    12  	"github.com/docker/docker/libnetwork/drivers/overlay/overlayutils"
    13  	"github.com/docker/docker/libnetwork/netutils"
    14  	"github.com/docker/docker/libnetwork/ns"
    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  	}
    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, vtepIPv6 bool) error {
    61  	vxlan := &netlink.Vxlan{
    62  		LinkAttrs: netlink.LinkAttrs{Name: name, MTU: mtu},
    63  		VxlanId:   int(vni),
    64  		Learning:  true,
    65  		Port:      int(overlayutils.VXLANUDPPort()),
    66  		Proxy:     true,
    67  		L3miss:    true,
    68  		L2miss:    true,
    69  	}
    70  
    71  	// The kernel restricts the destination VTEP (virtual tunnel endpoint) in
    72  	// VXLAN forwarding database entries to a single address family, defaulting
    73  	// to IPv4 unless either an IPv6 group or default remote destination address
    74  	// is configured when the VXLAN link is created.
    75  	//
    76  	// Set up the VXLAN link for IPv6 destination addresses by setting the VXLAN
    77  	// group address to the IPv6 unspecified address, like iproute2.
    78  	// https://github.com/iproute2/iproute2/commit/97d564b90ccb1e4a3c756d9caae161f55b2b63a2
    79  	// https://patchwork.ozlabs.org/project/netdev/patch/20180917171325.GA2660@localhost.localdomain/
    80  	if vtepIPv6 {
    81  		vxlan.Group = net.IPv6unspecified
    82  	}
    83  
    84  	if err := ns.NlHandle().LinkAdd(vxlan); err != nil {
    85  		return fmt.Errorf("error creating vxlan interface: %v", err)
    86  	}
    87  
    88  	return nil
    89  }
    90  
    91  func deleteInterface(name string) error {
    92  	link, err := ns.NlHandle().LinkByName(name)
    93  	if err != nil {
    94  		return fmt.Errorf("failed to find interface with name %s: %v", name, err)
    95  	}
    96  
    97  	if err := ns.NlHandle().LinkDel(link); err != nil {
    98  		return fmt.Errorf("error deleting interface with name %s: %v", name, err)
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  func deleteVxlanByVNI(path string, vni uint32) error {
   105  	nlh := ns.NlHandle()
   106  	if path != "" {
   107  		ns, err := netns.GetFromPath(path)
   108  		if err != nil {
   109  			return fmt.Errorf("failed to get ns handle for %s: %v", path, err)
   110  		}
   111  		defer ns.Close()
   112  
   113  		nlh, err = netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE)
   114  		if err != nil {
   115  			return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err)
   116  		}
   117  		defer nlh.Close()
   118  		err = nlh.SetSocketTimeout(soTimeout)
   119  		if err != nil {
   120  			log.G(context.TODO()).Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err)
   121  		}
   122  	}
   123  
   124  	links, err := nlh.LinkList()
   125  	if err != nil {
   126  		return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err)
   127  	}
   128  
   129  	for _, l := range links {
   130  		if l.Type() == "vxlan" && (vni == 0 || l.(*netlink.Vxlan).VxlanId == int(vni)) {
   131  			err = nlh.LinkDel(l)
   132  			if err != nil {
   133  				return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err)
   134  			}
   135  			return nil
   136  		}
   137  	}
   138  
   139  	return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni)
   140  }