Re: Regression on 10-RC5 with a multicast routing daemon

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Wed, 15 Jan 2014 15:34:30 +0400
  Olivier,

On Tue, Jan 14, 2014 at 05:51:53PM +0100, Olivier Cochard-Labbé wrote:
O> I'm trying to port a PIM sparse-mode daemon (
O> https://github.com/troglobit/pimd/) and I've meet a problem:
O> This daemon compile and run fine on FreeBSD 9.2 but on 10-RC5 this daemon
O> can't understand received multicast packets (received from other PIM
O> neighbors) and display this kind of error message in debug mode "warning -
O> Received packet from 10.0.12.2 shorter (28 bytes) than hdr+data length
O> (20+28)".
O> How to troubleshoot this problem ?
O> 
O> My current work of this port can be tested with theses commands:
O> 
O> cd /usr/ports
O> fetch -o ports.pimd.shar "
O> https://sourceforge.net/p/bsdrp/code/HEAD/tree/trunk/BSDRP/patches/ports.pimd.shar?format=raw
O> "
O> sh ./ports.pimd.shar
O> cd net/pimd
O> make install

TL;DR version: you need not subtract iphdrlen in 10.0. Code in igmp.c:accept_igmp()
should be smth like:

    iphdrlen  = ip->ip_hl << 2;
#ifdef RAW_INPUT_IS_RAW	/* Linux */
    ipdatalen = ntohs(ip->ip_len) - iphdrlen;
#else
 #if __FreeBSD_version >= 1000000
    ipdatalen = ip->ip_len - iphdrlen;
 #else
    ipdatalen = ip->ip_len;
 #endif
#endif

You can also look into quagga sources, file ospfd/ospf_packet.c, for more
examples of workarounds for this API mess.



Long story is the following. Historical behaviour of BSD raw sockets were
the following:

* packet is modified
  - packets' ip_len and ip_off are converted to host byte order
  - packets' ip_len is reduced by the actual size of IP header

This is an artefact from the fact that the kernel stack modified every
packet at the very beginning of its processing, and worked with it in this
form. It just didn't bother to convert it before passing to raw socket,
so raw socket wasn't truly _raw_. This is actually a bug.

Later, most non-BSD operating systems defined the following API for raw sockets:

* packet is passed unmodified

btw, I find this much better behavior.

Later, right before 9.0-RELEASE, in r226105 (merged to stable/9 as r226299)
Andre has changed behaviour to:

* packet is modified
  - packets' ip_len and ip_off are converted to host byte order

This appeared a huge disaster to a number of ports, thus it was backed out
in r227423 in stable/9. However this remained in head. We decided that all
ports should be fixed during two years up to 10.0-RELEASE.

Later on, there is a trend for BSD systems to convert their IP stacks to stop
modifying byte order internally in kernel. But the compatibility for the raw
sockets remained. This is what I did in FreeBSD in r241913 and in r241923.

Right now, looking behind, it seems to me that we should have convert raw
sockets to be truly raw, like in Linux, right in the 10-release cycle. The
API mess should be reduced.

According to comments in quagga, DragonFly has the following behavior:

* packet is modified
  - packets' ip_len is reduced by the actual size of IP header

Damn, what a mess. I'd like to go towards absolutely unmodified packets
for the 11-release cycle.

-- 
Totus tuus, Glebius.
Received on Wed Jan 15 2014 - 10:34:36 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:46 UTC