github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/osl/neigh_linux.go (about)

     1  package osl
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net"
     7  
     8  	"github.com/vishvananda/netlink"
     9  )
    10  
    11  // NeighOption is a function option type to set interface options
    12  type NeighOption func(nh *neigh)
    13  
    14  type neigh struct {
    15  	dstIP    net.IP
    16  	dstMac   net.HardwareAddr
    17  	linkName string
    18  	linkDst  string
    19  	family   int
    20  }
    21  
    22  func (n *networkNamespace) findNeighbor(dstIP net.IP, dstMac net.HardwareAddr) *neigh {
    23  	n.Lock()
    24  	defer n.Unlock()
    25  
    26  	for _, nh := range n.neighbors {
    27  		if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) {
    28  			return nh
    29  		}
    30  	}
    31  
    32  	return nil
    33  }
    34  
    35  func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, osDelete bool) error {
    36  	var (
    37  		iface netlink.Link
    38  		err   error
    39  	)
    40  
    41  	nh := n.findNeighbor(dstIP, dstMac)
    42  	if nh == nil {
    43  		return fmt.Errorf("could not find the neighbor entry to delete")
    44  	}
    45  
    46  	if osDelete {
    47  		n.Lock()
    48  		nlh := n.nlHandle
    49  		n.Unlock()
    50  
    51  		if nh.linkDst != "" {
    52  			iface, err = nlh.LinkByName(nh.linkDst)
    53  			if err != nil {
    54  				return fmt.Errorf("could not find interface with destination name %s: %v",
    55  					nh.linkDst, err)
    56  			}
    57  		}
    58  
    59  		nlnh := &netlink.Neigh{
    60  			IP:     dstIP,
    61  			State:  netlink.NUD_PERMANENT,
    62  			Family: nh.family,
    63  		}
    64  
    65  		if nlnh.Family > 0 {
    66  			nlnh.HardwareAddr = dstMac
    67  			nlnh.Flags = netlink.NTF_SELF
    68  		}
    69  
    70  		if nh.linkDst != "" {
    71  			nlnh.LinkIndex = iface.Attrs().Index
    72  		}
    73  
    74  		if err := nlh.NeighDel(nlnh); err != nil {
    75  			return fmt.Errorf("could not delete neighbor entry: %v", err)
    76  		}
    77  	}
    78  
    79  	n.Lock()
    80  	for i, nh := range n.neighbors {
    81  		if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) {
    82  			n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...)
    83  		}
    84  	}
    85  	n.Unlock()
    86  
    87  	return nil
    88  }
    89  
    90  func (n *networkNamespace) AddNeighbor(dstIP net.IP, dstMac net.HardwareAddr, options ...NeighOption) error {
    91  	var (
    92  		iface netlink.Link
    93  		err   error
    94  	)
    95  
    96  	nh := n.findNeighbor(dstIP, dstMac)
    97  	if nh != nil {
    98  		// If it exists silently return
    99  		return nil
   100  	}
   101  
   102  	nh = &neigh{
   103  		dstIP:  dstIP,
   104  		dstMac: dstMac,
   105  	}
   106  
   107  	nh.processNeighOptions(options...)
   108  
   109  	if nh.linkName != "" {
   110  		nh.linkDst = n.findDst(nh.linkName, false)
   111  		if nh.linkDst == "" {
   112  			return fmt.Errorf("could not find the interface with name %s", nh.linkName)
   113  		}
   114  	}
   115  
   116  	n.Lock()
   117  	nlh := n.nlHandle
   118  	n.Unlock()
   119  
   120  	if nh.linkDst != "" {
   121  		iface, err = nlh.LinkByName(nh.linkDst)
   122  		if err != nil {
   123  			return fmt.Errorf("could not find interface with destination name %s: %v",
   124  				nh.linkDst, err)
   125  		}
   126  	}
   127  
   128  	nlnh := &netlink.Neigh{
   129  		IP:           dstIP,
   130  		HardwareAddr: dstMac,
   131  		State:        netlink.NUD_PERMANENT,
   132  		Family:       nh.family,
   133  	}
   134  
   135  	if nlnh.Family > 0 {
   136  		nlnh.Flags = netlink.NTF_SELF
   137  	}
   138  
   139  	if nh.linkDst != "" {
   140  		nlnh.LinkIndex = iface.Attrs().Index
   141  	}
   142  
   143  	if err := nlh.NeighSet(nlnh); err != nil {
   144  		return fmt.Errorf("could not add neighbor entry: %v", err)
   145  	}
   146  
   147  	n.neighbors = append(n.neighbors, nh)
   148  
   149  	return nil
   150  }