On Fri, Feb 5, 2016 at 3:44 PM, sven falempin <[email protected]> wrote:
> > > On Fri, Feb 5, 2016 at 3:40 PM, sven falempin <[email protected]> > wrote: > >> Dear Allmighty Tech Readers, >> >> I recently found out that you cannot dhclient a carp iface. >> People jumped over that saying , blahblah must have ip . >> Lies ! CARP require the two interface to have the same ip, >> the mac will be the same so using dhcp to configure them is >> working by design. >> >> I have now a working solution , it s ugly, please consider >> helping cleaning >> this for future openbsd, it s really an improvement. >> >> I will follow demands to clean it. >> >> Problems : >> 1/ an invalid carp iface that is up, is considered down (not fixed), >> also send_msg is not possible on up carp without ip. Tested with ugly >> second chunk of dhclient.c patch >> 2/ dhclient is only accepting 'hardware' mac address >> 3/ when configuring interface , routehandler is having a similar problem >> than 1. First chunk in the diff >> >> CARP is obvisouly smart to cut communication of a backup interface, but i >> think >> invalid state is not backup state. So to fix 1 i would somehow consider >> active an invalid and up carp interface: make sense to me. This would fix >> 1. >> For now i just put a stupid ip with /32 subnet.... >> >> 2/ Is solved with the part of diff i think should be already integrated, >> see dispatch.c >> I am not sure if getifaddrs is badly coded though, and the sdl_type is >> somehow not set. >> carp GOT a mac address . >> >> 3/ Well i just cheated for this one , i am not good enough to play fair. >> >> >> Index: dhclient.c >> =================================================================== >> RCS file: /cvs/src/sbin/dhclient/dhclient.c,v >> retrieving revision 1.361 >> diff -u -p -r1.361 dhclient.c >> --- dhclient.c 18 May 2015 14:59:42 -0000 1.361 >> +++ dhclient.c 5 Feb 2016 20:22:16 -0000 >> @@ -323,6 +323,10 @@ routehandler(void) >> ifm = (struct if_msghdr *)rtm; >> if (ifm->ifm_index != ifi->index) >> break; >> + if (0 == strncmp("carp", ifi->name, 4)) { >> + note("rtm->rtm_flags(%08X) :%08X", >> rtm->rtm_flags, RTF_UP); >> + rtm->rtm_flags = rtm->rtm_flags | RTF_UP; // Can >> i be more ugly ? i wonder >> + } >> if ((rtm->rtm_flags & RTF_UP) == 0) { >> rslt = asprintf(&errmsg, "%s down", ifi->name); >> goto die; >> @@ -634,6 +638,11 @@ state_preboot(void) >> >> ifi->linkstat = interface_status(ifi->name); >> >> + if (0 == strncmp("carp", ifi->name, 4)) { >> + note("carp is not down it is invalid :s"); >> + ifi->linkstat = 1; >> + } >> + >> if (log_perror && interval > 3) { >> if (!preamble && !ifi->linkstat) { >> fprintf(stderr, "%s: no link ....", ifi->name); >> @@ -858,6 +867,8 @@ dhcpack(struct in_addr client_addr, stru >> >> /* Stop resending DHCPREQUEST. */ >> cancel_timeout(); >> + >> + note("Hello , we just get the data right"); >> >> bind_lease(); >> } >> Index: dispatch.c >> =================================================================== >> RCS file: /cvs/src/sbin/dhclient/dispatch.c,v >> retrieving revision 1.102 >> diff -u -p -r1.102 dispatch.c >> --- dispatch.c 18 May 2015 14:59:42 -0000 1.102 >> +++ dispatch.c 5 Feb 2016 20:22:16 -0000 >> @@ -78,7 +78,7 @@ get_hw_address(void) >> continue; >> >> sdl = (struct sockaddr_dl *)ifa->ifa_addr; >> - if (sdl->sdl_type != IFT_ETHER || >> + if ( !( sdl->sdl_type == IFT_ETHER || sdl->sdl_type == >> IFT_CARP ) || >> sdl->sdl_alen != ETHER_ADDR_LEN) >> continue; >> >> >> Test: >> >> # ifconfig em5 down; ifconfig em5 down #was having a address here to cvs >> # ifconfig carp1 vhid 55 carpdev em5 169.0.0.1 netmask 32 >> # CFLAGS=-g make && ./dhclient -d carp1 >> cc -g -Wall -Werror-implicit-function-declaration -c dhclient.c >> cc -static -pie -o dhclient dhclient.o clparse.o dispatch.o bpf.o >> options.o conflex.o errwarn.o packet.o tables.o parse.o privsep.o kroute. >> o -lutil >> DHCPDISCOVER on carp1 - interval 3 >> DHCPOFFER from 192.168.10.1 (fe:e1:ba:d0:1e:0d) >> DHCPREQUEST on carp1 to 255.255.255.255 >> DHCPACK from 192.168.10.1 (fe:e1:ba:d0:1e:0d) >> Hello , we just get the data right >> rtm->rtm_flags(FFFF8802) :00000001 >> bound to 192.168.10.151 -- renewal in 60 seconds. >> # # can now cvs diff like normal >> >> > PS: after first lease, the rtm flasg is up of course > bound to 192.168.10.151 -- renewal in 60 seconds. > rtm->rtm_flags(FFFF8843) :00000001 > rtm->rtm_flags(FFFF8843) :00000001 > DHCPREQUEST on carp1 to 192.168.10.1 > > > -- > > --------------------------------------------------------------------------------------------------------------------- > () ascii ribbon campaign - against html e-mail > /\ > tl;dr Digging a bit, carp is not handle like other interface there is no if_carp.c file or carp_X function. In if.c, the case is handle with if type = IFT_CARP statement. carp_carpdev_state is where the up/inactive reported status may be change, in ./sys/netinet/ip_carp.c for the ethernet address, a similar hax is made in the ioctl so set/get it: case IFT_ETHER: case IFT_CARP: case IFT_XETHER: case IFT_ISO88025: So dhclient should align to this somehow: - if (sdl->sdl_type != IFT_ETHER || + int is_ether = sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_CARP || sdl->sdl_type == IFT_XETHER || sdl->sdl_type == IFT_ISO88025; + if ( !( is_ether ) || getifsaddr calls sysctl_iflist, data from interface are dumped for the client, thus finding the IFT_CARP line 1291 of sys/net/rtsock.c: ifm->ifm_data = ifp->if_data; in the carp AF_LINK entry. tl;dr -- --------------------------------------------------------------------------------------------------------------------- () ascii ribbon campaign - against html e-mail /\
