On Fri, Feb 5, 2016 at 5:11 PM, sven falempin <[email protected]>
wrote:
>
>
> 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
>
>
To send/receive the DHCP protocol, carp must accept ethernet data in INIT
MODE,
The IFF_RUNNING flag can be avoided or not.
With this, and the IFT_CARP in dhclient , carp can be initialized by dhcp.
/!\ invalid diff wont apply, and just work in progress
Index: ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.264
diff -u -p -r1.264 ip_carp.c
--- ip_carp.c 2 Jul 2015 09:40:03 -0000 1.264
+++ ip_carp.c 7 Feb 2016 03:26:14 -0000
@@ -1394,9 +1396,19 @@ carp_ourether(void *v, u_int8_t *ena)
TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list) {
struct carp_vhost_entry *vhe;
+ LIST_FOREACH(vhe, &vh->carp_vhosts, vhost_entries) {
+ if ( vhe->vhid == 0 ) {
+ printf("squeeeze\n");
+ continue; //no ethernet if no vhid (no in
ipv6 mode maybe :p
+ }
+ if (vhe->state == INIT && !memcmp(ena,
vhe->vhe_enaddr,ETHER_ADDR_LEN)) { //IFF_UP|IFF_RUNNING must be checked too
+ return (&vh->sc_if);
+ }
+ }
if ((vh->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
- (IFF_UP|IFF_RUNNING))
+ (IFF_UP|IFF_RUNNING)) {
continue;
+ }
if (vh->sc_balancing == CARP_BAL_ARP) {
LIST_FOREACH(vhe, &vh->carp_vhosts, vhost_entries)
if (vhe->state == MASTER &&
@@ -1426,9 +1438,15 @@ carp_input(struct ifnet *ifp0, struct mb
eh = mtod(m, struct ether_header *);
cif = (struct carp_if *)ifp0->if_carp;
ifp = carp_ourether(cif, eh->ether_dhost);
- if (ifp == NULL && !ETHER_IS_MULTICAST(eh->ether_dhost))
+ if (ifp == NULL && !ETHER_IS_MULTICAST(eh->ether_dhost)) {
return (0);
+ }
if (ifp == NULL) {
struct carp_softc *vh;
@@ -1567,15 +1586,22 @@ carp_setrun(struct carp_vhost_entry *vhe
sc->sc_realmac = 0;
if (sc->sc_if.if_flags & IFF_UP && vhe->vhid > 0 &&
- (sc->sc_naddrs || sc->sc_naddrs6) && !sc->sc_suppress) {
+ /*(sc->sc_naddrs || sc->sc_naddrs6) &&*/ !sc->sc_suppress) {
+ printf( "%s: SET IFF_RUNNING 2\n", sc->sc_if.if_xname);
sc->sc_if.if_flags |= IFF_RUNNING;
} else {
sc->sc_if.if_flags &= ~IFF_RUNNING;
return;
}
+ if ( !sc->sc_naddrs && !sc->sc_naddrs6 ) {
+ return;
+ }
switch (vhe->state) {
case INIT:
carp_set_state(vhe, BACKUP);
carp_setrun(vhe, 0);
break;
@@ -2314,6 +2341,14 @@ carp_output(struct ifnet *ifp, struct mb
vhe = sc->cur_vhe ? sc->cur_vhe : LIST_FIRST(&sc->carp_vhosts);
+
+ if ((vhe->state == INIT)
+ && !sc->sc_naddrs && !sc->sc_naddrs6 //just PARANOIA
+ && vhe->vhid > 0 && sc->sc_carpdev) { //actually an INVALID
STATE would be nice { INVALID =-1, INIT, BACKUP, MASTER}
+ return (ether_output(ifp, m, sa, rt));
+ }
+
if ((sc->sc_carpdev == NULL) ||
(!sc->sc_balancing && vhe->state != MASTER)) {
m_freem(m);
@@ -2329,6 +2364,12 @@ carp_set_state_all(struct carp_softc *sc
struct carp_vhost_entry *vhe;
LIST_FOREACH(vhe, &sc->carp_vhosts, vhost_entries) {
+ if (vhe->state == INIT && vhe->vhid > 0) {
+ if (!sc->sc_naddrs && !sc->sc_naddrs6)
+ sc->sc_if.if_link_state = LINK_STATE_UP;
//we have mac, IP is down, but iface is ethernet valid
+ }
if (vhe->state == state)
continue;
@@ -2373,6 +2414,12 @@ carp_set_state(struct carp_vhost_entry *
case MASTER:
sc->sc_if.if_link_state = LINK_STATE_UP;
break;
+ case INIT:
+ if (sc->sc_naddrs || sc->sc_naddrs6) //MUST HAVE vhid too
+ sc->sc_if.if_link_state = LINK_STATE_DOWN;
+ else
+ sc->sc_if.if_link_state = LINK_STATE_UP;
+ break;
default:
sc->sc_if.if_link_state = LINK_STATE_INVALID;
break;
--
---------------------------------------------------------------------------------------------------------------------
() ascii ribbon campaign - against html e-mail
/\