mirror of https://github.com/vishvananda/netlink
ip neighbour: Add support for lladdr to be an IP address
The ip neighbour supports adding of peers statically using commands where the lladdr is an IP address. ip neighbor add 10.0.0.2 lladdr 203.0.113.6 dev tun8 This is used in the case of point-to-multipoint GRE to setup the remote end point of the tunnel Note that link-layer address and neighbor address are both IP addresses Signed-off-by: Manohar Castelino <manohar.r.castelino@intel.com>
This commit is contained in:
parent
8a610f1e24
commit
921f7441f1
1
neigh.go
1
neigh.go
|
@ -14,6 +14,7 @@ type Neigh struct {
|
|||
Flags int
|
||||
IP net.IP
|
||||
HardwareAddr net.HardwareAddr
|
||||
LLIPAddr net.IP //Used in the case of NHRP
|
||||
}
|
||||
|
||||
// String returns $ip/$hwaddr $label
|
||||
|
|
|
@ -128,6 +128,7 @@ func (h *Handle) NeighDel(neigh *Neigh) error {
|
|||
|
||||
func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||
var family int
|
||||
|
||||
if neigh.Family > 0 {
|
||||
family = neigh.Family
|
||||
} else {
|
||||
|
@ -151,7 +152,10 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
|||
dstData := nl.NewRtAttr(NDA_DST, ipData)
|
||||
req.AddData(dstData)
|
||||
|
||||
if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
|
||||
if neigh.LLIPAddr != nil {
|
||||
llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4())
|
||||
req.AddData(llIPData)
|
||||
} else if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
|
||||
hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
|
||||
req.AddData(hwData)
|
||||
}
|
||||
|
@ -237,12 +241,33 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// This should be cached for perfomance
|
||||
// once per table dump
|
||||
link, err := LinkByIndex(neigh.LinkIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encapType := link.Attrs().EncapType
|
||||
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case NDA_DST:
|
||||
neigh.IP = net.IP(attr.Value)
|
||||
case NDA_LLADDR:
|
||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||
// BUG: Is this a bug in the netlink library?
|
||||
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
||||
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
||||
attrLen := attr.Attr.Len - syscall.SizeofRtAttr
|
||||
if attrLen == 4 && (encapType == "ipip" ||
|
||||
encapType == "sit" ||
|
||||
encapType == "gre") {
|
||||
neigh.LLIPAddr = net.IP(attr.Value)
|
||||
} else if attrLen == 16 &&
|
||||
encapType == "tunnel6" {
|
||||
neigh.IP = net.IP(attr.Value)
|
||||
} else {
|
||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,15 @@ func dumpContains(dump []Neigh, e arpEntry) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func dumpContainsNeigh(dump []Neigh, ne Neigh) bool {
|
||||
for _, n := range dump {
|
||||
if n.IP.Equal(ne.IP) && n.LLIPAddr.Equal(ne.LLIPAddr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func dumpContainsProxy(dump []Neigh, p proxyEntry) bool {
|
||||
for _, n := range dump {
|
||||
if n.IP.Equal(p.ip) && (n.LinkIndex == p.dev) && (n.Flags&NTF_PROXY) == NTF_PROXY {
|
||||
|
@ -43,6 +52,54 @@ func dumpContainsProxy(dump []Neigh, p proxyEntry) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func TestNeighAddDelLLIPAddr(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
dummy := Iptun{
|
||||
LinkAttrs: LinkAttrs{Name: "neigh0"},
|
||||
PMtuDisc: 1,
|
||||
Local: net.IPv4(127, 0, 0, 1),
|
||||
Remote: net.IPv4(127, 0, 0, 1)}
|
||||
if err := LinkAdd(&dummy); err != nil {
|
||||
t.Errorf("Failed to create link: %v", err)
|
||||
}
|
||||
ensureIndex(dummy.Attrs())
|
||||
|
||||
entry := Neigh{
|
||||
LinkIndex: dummy.Index,
|
||||
State: NUD_PERMANENT,
|
||||
IP: net.IPv4(198, 51, 100, 2),
|
||||
LLIPAddr: net.IPv4(198, 51, 100, 1),
|
||||
}
|
||||
|
||||
err := NeighAdd(&entry)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to NeighAdd: %v", err)
|
||||
}
|
||||
|
||||
// Dump and see that all added entries are there
|
||||
dump, err := NeighList(dummy.Index, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to NeighList: %v", err)
|
||||
}
|
||||
|
||||
if !dumpContainsNeigh(dump, entry) {
|
||||
t.Errorf("Dump does not contain: %v: %v", entry, dump)
|
||||
|
||||
}
|
||||
|
||||
// Delete the entry
|
||||
err = NeighDel(&entry)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to NeighDel: %v", err)
|
||||
}
|
||||
|
||||
if err := LinkDel(&dummy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNeighAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
|
Loading…
Reference in New Issue