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
|
Flags int
|
||||||
IP net.IP
|
IP net.IP
|
||||||
HardwareAddr net.HardwareAddr
|
HardwareAddr net.HardwareAddr
|
||||||
|
LLIPAddr net.IP //Used in the case of NHRP
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns $ip/$hwaddr $label
|
// String returns $ip/$hwaddr $label
|
||||||
|
|
|
@ -128,6 +128,7 @@ func (h *Handle) NeighDel(neigh *Neigh) error {
|
||||||
|
|
||||||
func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||||
var family int
|
var family int
|
||||||
|
|
||||||
if neigh.Family > 0 {
|
if neigh.Family > 0 {
|
||||||
family = neigh.Family
|
family = neigh.Family
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,7 +152,10 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||||
dstData := nl.NewRtAttr(NDA_DST, ipData)
|
dstData := nl.NewRtAttr(NDA_DST, ipData)
|
||||||
req.AddData(dstData)
|
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))
|
hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
|
||||||
req.AddData(hwData)
|
req.AddData(hwData)
|
||||||
}
|
}
|
||||||
|
@ -237,12 +241,33 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||||
return nil, err
|
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 {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case NDA_DST:
|
case NDA_DST:
|
||||||
neigh.IP = net.IP(attr.Value)
|
neigh.IP = net.IP(attr.Value)
|
||||||
case NDA_LLADDR:
|
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
|
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 {
|
func dumpContainsProxy(dump []Neigh, p proxyEntry) bool {
|
||||||
for _, n := range dump {
|
for _, n := range dump {
|
||||||
if n.IP.Equal(p.ip) && (n.LinkIndex == p.dev) && (n.Flags&NTF_PROXY) == NTF_PROXY {
|
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
|
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) {
|
func TestNeighAddDel(t *testing.T) {
|
||||||
tearDown := setUpNetlinkTest(t)
|
tearDown := setUpNetlinkTest(t)
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
|
Loading…
Reference in New Issue