mdlayher / arp

Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed.

Home Page:https://tools.ietf.org/html/rfc826

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support infiniband device

jcatana opened this issue · comments

Trying to use a downsteam package that references this repo. I ran into an issue using IP over Infiniband device type in a mix ethernet/infiniband environment.

 ib0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 4092 qdisc mq state UP mode DEFAULT group default qlen 256
    link/infiniband 20:00:00:67:fe:80:00:00:00:00:00:00:e0:07:1b:ff:ff:7d:e2:e8 brd 00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff

Infiniband devices use 12 digit mac addresses and this probably unnecessary sanity check in packet.go causes error.
Lines 90-92:

	if len(srcHW) != len(dstHW) {
		return nil, ErrInvalidHardwareAddr
	}

It assumes all MAC addresses are 6 character.
Removing the check and recompiling allowed downstream Metallb to work on my IP over Infiniband interconnects.

Neat. I'm good with that. Mind sending a PR?

Actually, why would that check cause an issue? The surrounding code just checks for MAC addresses of at least length 6.

Yeah, that is fine, but the if len(srcHW) != len(dstHW) fails it . My source is 12 and dst is 6

Apologies, I haven't ever tried that. How does that work? I'd expect that you'd be ARPing to another IPoIB device on the other side that also has a 12 byte address.

The ARP packet allocates enough space for the length of the source address at the moment, so the 6 empty bytes on the destination are just ignored?

I'm happy to loosen the restriction, I'd just like to understand what's going on here. If you have some links, that'd be helpful.

In addition, this RFC seems to indicate both addresses would be 20 bytes: https://tools.ietf.org/html/rfc4391#section-9.2.

Maybe it's upstream for you in "net" because I think that's how you are getting MAC address.
How can I help debug this and see what is being compared at that point? Just add fmt module and print it out? I've tried but I'm fairly bad at go.

From MetalLB:
https://github.com/danderson/metallb/blob/30e6f68bade331367ddb3a772593d137af21e4d8/internal/layer2/arp.go#L52

pkt, err := arp.NewPacket(op, a.hardwareAddr, ip, ethernet.Broadcast, ip)

As from the above, it use ethernet.Broadcast as dstHW (Gratuitous ARP). And that's why it always fail for IP over Infiniband( 20bytes)

I belief removing the check would resolve the issue or check for destHW is not equal to ethernet.Broadcast too.

EDIT: MetalLB in L2 mode uses gratuitous ARP.

Let me know if this is all set now, thanks!