github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/drivers/overlay/ov_utils.go (about)

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