K 10 svn:author V 5 luigi K 8 svn:date V 27 2009-12-27T19:17:03.207078Z K 7 svn:log V 1886 Historically, BSD keeps ip_len and ip_off in host format when doing layer 3 processing. This often requires to translate the format back and forth. I suppose the original motivation was to avoid carrying additional metadata, and/or save a couple of local variables to store off and len. My impression is that nowadays there are much bigger disadvantages: - many unnecessary writes to the mbuf, which make it harder to share the data, and also cause cache traffic; - visual clutter in the code; - portability problems, either across layers (e.g. we cannot use the same code to do deep packet inspection for L2 and L3 packets) or across operating systems; - potential source of confusion, because the format is different in different parts of the code. Eventually, I would like these fields to remain in network format across the lifetime of a packet, but this may take a long time, so let's see if we can find ways to at least make the switch easier. Here I define a couple of macros that do the format conversion back and forth. On BIG_ENDIAN machines, or when we will switch, they become no-ops. At the moment I am only using these macros in the ipfw code, I am not sure this is the best solution across the entire stack. #if (BYTE_ORDER == BIG_ENDIAN) || defined(HAVE_NET_IPLEN) #define SET_NET_IPLEN(p) do {} while (0) #define SET_HOST_IPLEN(p) do {} while (0) #else #define SET_NET_IPLEN(p) do { \ struct ip *h_ip = (p); \ h_ip->ip_len = htons(h_ip->ip_len); \ h_ip->ip_off = htons(h_ip->ip_off); \ } while (0) #define SET_HOST_IPLEN(p) do { \ struct ip *h_ip = (p); \ h_ip->ip_len = ntohs(h_ip->ip_len); \ h_ip->ip_off = ntohs(h_ip->ip_off); \ } while (0) #endif /* !HAVE_NET_IPLEN */ END