Repository navigation
Conversation
Signed-off-by: Andreas Roeseler <[email protected]>
fenner
left a comment
There was a problem hiding this comment.
Thanks for the great start on PROBE support! While I have several comments, I believe all of them are minor.
I have two different test resources to help with testing these changes:
- A synthetic probe responder, which responds with a different response to each request, then a timeout, then starts cycling around from the beginning again. This way, you don't have to manually create a situation that invokes a given response; just run against an instance of this responder. It's a standalone script written in python, that uses the scapy packet library. It's available from https://github.com/aristanetworks/probe-tools
- tcpdump patches that print PROBE requests/replies, including checking the checksum, etc.
| icp->un.echo.sequence |= htons(1); /* Set L-bit */ | ||
| WRITE_VERSION(ext.v_rsvd , 2); | ||
| ext.v_rsvd = htons(ext.v_rsvd); | ||
| ext.checksum = 0; |
There was a problem hiding this comment.
You must fill in the checksum later. While it appears that the Linux kernel does not check the checksum, there are other probe implementations that do.
My tcpdump update the-tcpdump-group/tcpdump#1115 will check that it's filled in properly.
| /* These checks mimic kernel checks in dev_valid_name */ | ||
| if (*name == '\0') | ||
| return -1; | ||
| if (strlen(name) >= IFNAMSIZ) |
There was a problem hiding this comment.
This limit only exists in Linux. Imagine running this against a router with an interface name TwentyFiveGigabitEthernet3/0/1
| return -1; | ||
|
|
||
| while (*name) { | ||
| if (*name == '/' || isspace(*name)) |
There was a problem hiding this comment.
As mentioned above, slashes are common in interface names. RFC8335 only limits interface names by referring to RFC7223, which says that they are yang strings.
| return 1; | ||
|
|
||
| sequence = ntohs(icmph->icmp6_seq); | ||
| state = icmph->icmp6_seq & 0xe0; |
There was a problem hiding this comment.
You forgot to shift this right by 5, so the switch below won't hit any of the cases.
| case 4: | ||
| printf("Error: Multiple Interfaces Satisfy Query\n"); | ||
| break; | ||
| default: |
There was a problem hiding this comment.
An invalid code (5 or above) will result in no error, and no output from the "code == 0" case below. This will likely be fairly confusing. Sure, it shouldn't happen, but, let's try to confuse the user less if it does occur.
| if (sequence & ICMP_EXT_ECHOREPLY_IPV4) | ||
| printf(" IPV4"); | ||
| if (sequence & ICMP_EXT_ECHOREPLY_IPV6) | ||
| printf(" IPV6"); |
There was a problem hiding this comment.
There's an unusual situation when the status is active, but there is no v4 or v6 configured. I suggest printing out something specific when (!sequence & (ICMP_EXT_ECHOREPLY_IPV4| ICMP_EXT_ECHOREPLY_IPV6)).
| if (sequence & ICMP_EXT_ECHOREPLY_IPV6) | ||
| printf(" IPV6"); | ||
| printf("\n"); | ||
| } |
There was a problem hiding this comment.
The else case here is significant: if you sent a query about an interface, and A=0, that is something the user probably really wants to know. Maybe
} else {
printf("Status: INACTIVE\n");
}
| default: | ||
| break; | ||
| } | ||
| switch (state) { |
There was a problem hiding this comment.
The returned state value is only valid if code == 0 and the transmitted L flag is 0; I recommend checking that here.
| default: | ||
| break; | ||
| } | ||
| if (icmph->icmp6_code == 0) { |
There was a problem hiding this comment.
The returned A/4/6 values are only valid if code=0 and L=1, I recommend checking that here.
| icmph->icmp6_id = rts->ident; | ||
| /* PROBE messages use only the first 8 bits as sequence number */ | ||
| icmph->icmp6_dataun.icmp6_un_data8[2] = rts->ntransmitted + 1; | ||
| icmph->icmp6_dataun.icmp6_un_data8[3] = 1; /* Set L-bit */ |
There was a problem hiding this comment.
I recommend giving the user an argument to control this (e.g., "--remote") - this is one of the most important pieces of PROBE functionality. In the case where the L-bit is clear, the only valid ctype is ICMP_EXT_ECHO_CTYPE_ADDR, but otherwise all the rest of the code applies.
|
Oh, one more thought here: when running the client on a system without the necessary kernel updates (pre-5.14, afaik), the
strace says: |
|
If the system is using the raw socket (e.g., the user's gid is not inside |
|
I've created issues for all of my comments at https://github.com/aristanetworks/iputils/issues and intend to work on addressing them. See https://github.com/aristanetworks/iputils/wiki for more information. |
This is a continuation of a project with slang21 and an update to the existing pull request found here: #328
This pull request adds timestamp info to the probe messages, fixes a bug in calculating the ctype of the message, and adds probing by ICMPV6 messages.
Original pull request blurb:
RFC 8335 describes the use of extended echo requests to probe specific network interfaces. This PR adds the -e flag to the ping command to probe specific interfaces and receive responses from those interfaces. Functionality for RFC 8335 was recently included in Linux net-next.
Usage:
ping -e [interface] [address]
Interface can be specified by name, ifindex, or IPV4 or IPV6 address.
ping -e 1 10.0.0.89
PING 10.0.0.89 (10.0.0.89) 56(84) bytes of data.
Interface: 1
Status: ACTIVE IPV4 IPV6
64 bytes from 10.0.0.89: icmp_seq=1 ttl=64 time=2.30 ms
--- 10.0.0.89 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.298/2.298/2.298/0.000 ms
This has been tested using interoperability with Wireshark and the net-next linux branch. The IPV4 PROBE response has been merged into the mainline Linux 5.13 version, and the IPV6 PROBE response has been merged into the net-next Linux branch and will be available in Linux 5.14.