* Johan Ymerson <[email protected]> [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, [email protected], [email protected] 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/
