nanog mailing list archives

Re: Experiences with IPv6 and Routing Efficiency


From: Owen DeLong <owen () delong com>
Date: Tue, 21 Jan 2014 13:58:43 -0800


On Jan 21, 2014, at 02:52 , Frank Habicht <geier () geier ne tz> wrote:

Hi Owen,

On 1/21/2014 12:13 PM, Owen DeLong wrote:
On Jan 18, 2014, at 23:19 , Frank Habicht <geier () geier ne tz> wrote:
c) v6 with a few extension headers
In this case, it will be at 40+o+n octets into the packet where o is the
number of octets contained in headers prior to the TCP header and n is
defined as in (b) above.

my point tried to be that it can be hard for an ASIC to know 'o'

now program a chip to filter based on this port number...
I think you might want to be more specific. After all, an ARM 9 is a
chip which can easily be programmed to do so (in fact, I can point to
iptables/ip6tables as running code which does this on the ARM 9).

I was thinking about hardware that's forwarding packets "not in software"
some of those boxes probably want to limit tcp ports 179 and 22.

The difference between hardware and software gets blurrier every day.

For example, many of the "forwarding ASICs" today are actually FPGAs with "software" loaded into them to do certain 
forwarding tasks.

Yes, I took it to extremes by proposing a more general purpose CPU, but the fact of the matter remains that traversing 
a header chain in software looking for a known header type that you care about actually isn't complex and can easily be 
implemented in hardware. The task boils down to:

octet i = &packet header;
while (headers_remaining && header_type != type_of_interest)
{
  header_type = i[NEXT_HEADER];
  i += (i[HDR_LEN]+1) * 8;
  if (header_type != 0 && header_type != 60 && header_type != 43 && header_type != 44 && header_type != 51 &&
        header_type != 50 && header_type != 60 && header_type != 135) headers_remaining = 0;
 }
if (headers_remaining)
{
        INSPECT THIS HEADER and act accordingly;
}
else
{
        Punt, header not present;
}

Not a particularly complex program for a modern ASIC, actually.

Where you run into potential problems (and this can apply to IPv4 as well, though less likely) is if you get an IPv6 
packet where the header chain is so unreasonably long that the header you want is not in the first fragment.

With a minimum MTU of 1280 octets, it's almost impossible to create a legitimate packet with a header chain so long 
that this would be an issue. That is one of the reasons that there are proposals to consider such packets invalid and 
why I support those proposals. However, those have nothing to do with ASIC difficulty. The fragment problem is hard to 
solve no matter how much CPU you throw at it because unless you are the end receiving host, you cannot reliably expect 
to be able to perform reassembly.


So... I suppose that whether your complaint has merit depends entirely
on whether or not extension headers become more common on IPv6 packets
than options have become on IPv4 packets or not and also on how hard it
is to build fast-path hardware that bypasses extension headers that it
does not care about. Since you only need to parse the first two fields
                                ^^^^ ?
of each extension header (Next Header Type and Header Length) 
... recursively for all extension headers ...

Which in anything but the most contrived of cases is likely n=0 for 95+% of all (unencrypted) packets and likely n<4 
for all others.

Further, it's not recursively, it's repetitively. There is a difference. (See above. Note that the loop is _NOT_ 
recursive, it is repetitive. Recursive would be something like:

sub parse_next_header(header)
{
        char * i = header;
        HDR_PARSE_RESULT result;
        register char nh = i[NExT_HEADER];
        if (nh != 0 && nh != 60 && nh != 43 && nh != 44 && nh != 51 && nh != 50 && nh != 60 && nh != 135)
                result = parse_next_header(i+(1+i[HDR_LEN])*8);
        // code to parse this header (modifies result accordingly)
        return (result);
}

This might be possible to do in an ASIC, but might be more difficult than the iterative solution proposed above.


to know
everything you need to bypass the current header, it shouldn't be too
hard to code that into a chip...
who's done that so far?

I don't know.

Up to what number of EHs or octet-length?

Why would the number of HEs or the octet-length (up to the maximum MTU supported by the box) matter in this question?

I understand that if you do it recursively, you get into potential stack resource issues, but with an iterative 
approach looking for the header of interest, I don't see the issue.

Owen



Current thread: