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
/\

Reply via email to