* Johan Ymerson <johan.ymer...@transmode.com> [2015-05-19 19:25]:
> On Tue, 2015-05-19 at 11:16 +0000, Johan Ymerson wrote:
> > On Tue, 2015-05-19 at 11:24 +0100, Stuart Henderson wrote:
> > > On 2015/05/19 10:10, Johan Ymerson wrote:
> > > Yes I understand that, but if carp init was counted in "LINK_STATE_DOWN"
> > > then the metric would be 65535 which I think would still avoid the
> > > problem you're seeing, and would involve less special-casing in ospfd.
> > Yes, that would also resolve the issue, but it is a bit illogical to
> > announce a network we cannot possibly route traffic to (due to hardware
> > problems).
> After some more testing I think we can conclude that this is most
> definitely a kernel issue.

hmm. there's definately more to it.

> If the network cable is unplugged while the machine is running, ifconfig
> reports the following:
> carp2: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
>         lladdr 00:00:5e:00:01:03
>         priority: 0
>         carp: INIT carpdev em2 vhid 3 advbase 1 advskew 100
>         groups: carp
>         status: invalid
>         inet 192.168.254.1 netmask 0xfffffe00 broadcast 192.168.255.255
> In this case network is announced with the correct metric (65535).
> 
> However, if the machine is started with the cable unplugged, ifconfig
> instead reports this:
> carp2: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
>         lladdr 00:00:5e:00:01:03
>         priority: 0
>         carp: INIT carpdev em2 vhid 3 advbase 1 advskew 100
>         groups: carp
>         inet 192.168.254.1 netmask 0xfffffe00 broadcast 192.168.255.255
> In this case the network is incorrectly announced as available with low
> metric.
> 
> Initializing if_link_state in the kernel carp code does seem to fix the
> issue:
> Index: sys/netinet/ip_carp.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_carp.c,v
> retrieving revision 1.247
> diff -u -p -r1.247 ip_carp.c
> --- sys/netinet/ip_carp.c       4 Mar 2015 10:59:52 -0000       1.247
> +++ sys/netinet/ip_carp.c       19 May 2015 17:22:18 -0000
> @@ -751,6 +751,7 @@ carp_clone_create(ifc, unit)
>         ifp->if_addrlen = ETHER_ADDR_LEN;
>         ifp->if_hdrlen = ETHER_HDR_LEN;
>         ifp->if_mtu = ETHERMTU;
> +       ifp->if_link_state = LINK_STATE_INVALID;
>         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
>         IFQ_SET_READY(&ifp->if_snd);
>         if_attach(ifp);

just for completeness: LINK_STATE_INVALID is 1, and that's what
carp_set_state uses for everything but master and backup. so far so
good.

ifp is part of the sc which in turn is malloc'd with M_ZERO in
carp_clone_create, so link state will be 0 aka LINK_STATE_UNKNOWN.

however, at the end of carp_clone_create, we call
carp_set_state_all(sc, INIT) which should take care of that.

Now the question is why that doesn't work, your one-liner above SHOULD
not make a difference. Either the fact that you set the link state
before if_attach() makes a difference (I don't see how atm), or
something isn't working as expected/intended in carp_set_state_all()
resp. its sibling carp_set_state(). printf debugging time?

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/

Reply via email to