On 03/10/14(Fri) 14:46, Stefan Sperling wrote:
> The IPv6 source address selection algorithm breaks ties by performing a
> bitwise match of each candidate source address against the destination
> address. The longest matching source address wins, regardless of which
> interface the source address came from.
> 
> In my carp setup, this is causing a problem.
> 
> Consider the carp address 2001:DB8:10::14, which is configured on
> firewall A (carp master state) and firewall B (carp backup state),
> each of which has another address in the same prefix on a non-carp
> interface (A has 2001:DB8:10::1 and B has 2001:DB8:10::11).
> 
> In this setup, connecting from A to B or from B to A via IPv6 is impossible.
> A will use 2001:DB8:10::14 as source address when it sends neighbour
> solicitations to B (2001:DB8:10::11). Since 2001:DB8:10::14 is a local
> address from B's point of view, B doesn't reply to neighbour solicitations
> sent by A. The only currently available workaround is to re-configure
> addresses in a way that outsmarts the longest match check such that a
> carp address always loses the tie. (Another workaround is to use IPv4
> which doesn't have this problem.)
> 
> The hack below special-cases carp interfaces: If there is a tie, then a
> carp interface is not allowed to win even if it has a longer bitwise match.
> (The carp interface is in master state here -- carp interfaces in backup
> state are never considered for source addresses in the first place.)
> 
> This hack makes communication between A and B work over IPv6 in the
> above scenario.

I think this hack makes sense.  I'm really afraid of the carp tentacles,
but I don't think there's a better way of solving this problem right
now.

This change is similar to the "let's move the cloning route" hack for
IPv4, since it gives a higher ``priority'' to any non-carp interface
when selecting source addresses, right?

> I also considered another solution: Make carp backups treat their
> local carp address as a non-local address. However, this would
> be a much more invasive change and would also affect IPv4.

This is certainly not an easy change, and it definitively comes with its
own specific dragons, but I believe that it would remove a lot of hacks
in the stack.

> -                     if (matchcmp > 0) /* (8) */
> +                     if (matchcmp > 0) { /* (8) */
> +#if NCARP > 0
> +                             /* 
[...]
> +                              */
> +                             if (ifp->if_type == IFT_CARP)
> +                                     continue;
> +#endif
>                               goto replace;
> +                     }

What if oifp is also a carp interface?  Is it possible?  Shouldn't you
use the pattern of in_addprefix():

                if (ifp->if_type == IFT_CARP &&
                    oifp->if_type != IFT_CARP)
                    continue;


Either way I'm ok with your diff.

Reply via email to