func (n *networkNamespace) AddNeighbor(dstIP net.IP, dstMac net.HardwareAddr, options ...NeighOption) error {
	nh := n.findNeighbor(dstIP, dstMac)
	if nh != nil {
		// If it exists silently return
		return nil
	}

	nh = &neigh{
		dstIP:  dstIP,
		dstMac: dstMac,
	}

	nh.processNeighOptions(options...)

	if nh.linkName != "" {
		nh.linkDst = n.findDst(nh.linkName, false)
		if nh.linkDst == "" {
			return fmt.Errorf("could not find the interface with name %s", nh.linkName)
		}
	}

	return nsInvoke(n.nsPath(), func(nsFD int) error { return nil }, func(callerFD int) error {
		var iface netlink.Link

		if nh.linkDst != "" {
			var err error
			iface, err = netlink.LinkByName(nh.linkDst)
			if err != nil {
				return fmt.Errorf("could not find interface with destination name %s: %v",
					nh.linkDst, err)
			}
		}

		nlnh := &netlink.Neigh{
			IP:           dstIP,
			HardwareAddr: dstMac,
			State:        netlink.NUD_PERMANENT,
			Family:       nh.family,
		}

		if nlnh.Family > 0 {
			nlnh.Flags = netlink.NTF_SELF
		}

		if nh.linkDst != "" {
			nlnh.LinkIndex = iface.Attrs().Index
		}

		if err := netlink.NeighSet(nlnh); err != nil {
			return fmt.Errorf("could not add neighbor entry: %v", err)
		}

		n.neighbors = append(n.neighbors, nh)

		return nil
	})
}
Beispiel #2
0
func (dev *vxlanDevice) AddL3(n neigh) error {
	log.Infof("calling NeighSet: %v, %v", n.IP, n.MAC)
	return netlink.NeighSet(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Type:         syscall.RTN_UNICAST,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}
func (*nl) SetNeigh(neigh *netlink.Neigh) error {
	return netlink.NeighSet(neigh)
}