Let's factorize some bits from arpinput() to make it more readable!

This introduce arpreply() which looks like arprequest() but is used
to answer requests.

At the same time I get rid of the ``eaddr'' argument of carp_iamatch(),
bluhm@ and Florian Riehm confirmed that it is not needed.

ok?

diff --git sys/netinet/if_ether.c sys/netinet/if_ether.c
index 3cade1b..b16d9d4 100644
--- sys/netinet/if_ether.c
+++ sys/netinet/if_ether.c
@@ -84,6 +84,7 @@ struct rtentry *arplookup(struct in_addr *, int, int, 
unsigned int);
 void in_arpinput(struct ifnet *, struct mbuf *);
 void in_revarpinput(struct ifnet *, struct mbuf *);
 int arpcache(struct ifnet *, struct ether_arp *, struct rtentry *);
+void arpreply(struct ifnet *, struct mbuf *, struct in_addr *, uint8_t *);
 
 LIST_HEAD(, llinfo_arp) arp_list;
 struct pool arp_pool;          /* pool for llinfo_arp structures */
@@ -262,6 +263,33 @@ arprequest(struct ifnet *ifp, u_int32_t *sip, u_int32_t 
*tip, u_int8_t *enaddr)
        ifp->if_output(ifp, m, &sa, NULL);
 }
 
+void
+arpreply(struct ifnet *ifp, struct mbuf *m, struct in_addr *sip, uint8_t 
*eaddr)
+{
+       struct ether_header *eh;
+       struct ether_arp *ea;
+       struct sockaddr sa;
+
+       ea = mtod(m, struct ether_arp *);
+       ea->arp_op = htons(ARPOP_REPLY);
+       ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
+
+       /* We're replying to a request. */
+       memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
+       memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa));
+
+       memcpy(ea->arp_sha, eaddr, sizeof(ea->arp_sha));
+       memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa));
+
+       eh = (struct ether_header *)sa.sa_data;
+       memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
+       memcpy(eh->ether_shost, eaddr, sizeof(eh->ether_shost));
+       eh->ether_type = htons(ETHERTYPE_ARP);
+       sa.sa_family = pseudo_AF_HDRCMPLT;
+       sa.sa_len = sizeof(sa);
+       ifp->if_output(ifp, m, &sa, NULL);
+}
+
 /*
  * Resolve an IP address into an ethernet address.  If success,
  * desten is filled in.  If there is no entry in arptab,
@@ -428,12 +456,9 @@ void
 in_arpinput(struct ifnet *ifp, struct mbuf *m)
 {
        struct ether_arp *ea;
-       struct ether_header *eh;
        struct rtentry *rt = NULL;
-       struct sockaddr sa;
        struct sockaddr_in sin;
        struct in_addr isaddr, itaddr;
-       uint8_t enaddr[ETHER_ADDR_LEN];
        char addr[INET_ADDRSTRLEN];
        int op, target = 0;
        unsigned int rdomain;
@@ -459,8 +484,7 @@ in_arpinput(struct ifnet *ifp, struct mbuf *m)
                goto out;
        }
 
-       memcpy(enaddr, LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
-       if (!memcmp(ea->arp_sha, enaddr, sizeof(ea->arp_sha)))
+       if (!memcmp(ea->arp_sha, LLADDR(ifp->if_sadl), sizeof(ea->arp_sha)))
                goto out;       /* it's from me, ignore it. */
 
        /* Check target against our interface addresses. */
@@ -474,7 +498,7 @@ in_arpinput(struct ifnet *ifp, struct mbuf *m)
 
 #if NCARP > 0
        if (target && op == ARPOP_REQUEST && ifp->if_type == IFT_CARP &&
-           !carp_iamatch(ifp, enaddr))
+           !carp_iamatch(ifp))
                goto out;
 #endif
 
@@ -500,43 +524,28 @@ in_arpinput(struct ifnet *ifp, struct mbuf *m)
                }
        }
 
-       if (op != ARPOP_REQUEST)
-               goto out;
-
-       rtfree(rt);
-       if (target) {
-               /* We are the target and already have all info for the reply */
-               memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
-               memcpy(ea->arp_sha, LLADDR(ifp->if_sadl), sizeof(ea->arp_sha));
-       } else {
-               struct sockaddr_dl *sdl;
+       if (op == ARPOP_REQUEST) {
+               uint8_t *eaddr;
 
-               rt = arplookup(&itaddr, 0, SIN_PROXY, rdomain);
-               if (rt == NULL)
-                       goto out;
-               /* protect from possible duplicates only owner should respond */
-               if (rt->rt_ifidx != ifp->if_index)
-                       goto out;
-               memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
-               sdl = satosdl(rt->rt_gateway);
-               memcpy(ea->arp_sha, LLADDR(sdl), sizeof(ea->arp_sha));
+               if (target) {
+                       /* We already have all info for the reply */
+                       eaddr = LLADDR(ifp->if_sadl);
+               } else {
+                       rtfree(rt);
+                       rt = arplookup(&itaddr, 0, SIN_PROXY, rdomain);
+                       /*
+                        * Protect from possible duplicates, only owner
+                        * should respond
+                        */
+                       if ((rt == NULL) || (rt->rt_ifidx != ifp->if_index))
+                               goto out;
+                       eaddr = LLADDR(satosdl(rt->rt_gateway));
+               }
+               arpreply(ifp, m, &itaddr, eaddr);
                rtfree(rt);
+               return;
        }
 
-       memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa));
-       memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
-       ea->arp_op = htons(ARPOP_REPLY);
-       ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
-       eh = (struct ether_header *)sa.sa_data;
-       memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
-       memcpy(eh->ether_shost, enaddr, sizeof(eh->ether_shost));
-
-       eh->ether_type = htons(ETHERTYPE_ARP);
-       sa.sa_family = pseudo_AF_HDRCMPLT;
-       sa.sa_len = sizeof(sa);
-       ifp->if_output(ifp, m, &sa, NULL);
-       return;
-
 out:
        rtfree(rt);
        m_freem(m);
diff --git sys/netinet/ip_carp.c sys/netinet/ip_carp.c
index d9fff88..eac5673 100644
--- sys/netinet/ip_carp.c
+++ sys/netinet/ip_carp.c
@@ -1321,7 +1321,7 @@ carp_update_lsmask(struct carp_softc *sc)
 }
 
 int
-carp_iamatch(struct ifnet *ifp, uint8_t *enaddr)
+carp_iamatch(struct ifnet *ifp)
 {
        struct carp_softc *sc = ifp->if_softc;
        struct carp_vhost_entry *vhe;
@@ -1329,14 +1329,8 @@ carp_iamatch(struct ifnet *ifp, uint8_t *enaddr)
        int match = 0;
 
        vhe = SRPL_ENTER(&sr, &sc->carp_vhosts); /* head */
-       if (vhe->state == MASTER) {
-               if (sc->sc_balancing == CARP_BAL_IPSTEALTH ||
-                   sc->sc_balancing == CARP_BAL_IP) {
-                       struct arpcom *ac = (struct arpcom *)sc->sc_carpdev;
-                       memcpy(enaddr, ac->ac_enaddr, ETHER_ADDR_LEN);
-               }
+       if (vhe->state == MASTER)
                match = 1;
-       }
        SRPL_LEAVE(&sr);
 
        return (match);
diff --git sys/netinet/ip_carp.h sys/netinet/ip_carp.h
index fbf5f06..47e305e 100644
--- sys/netinet/ip_carp.h
+++ sys/netinet/ip_carp.h
@@ -167,7 +167,7 @@ void                 carp_proto_input (struct mbuf *, ...);
 void            carp_carpdev_state(void *);
 void            carp_group_demote_adj(struct ifnet *, int, char *);
 int             carp6_proto_input(struct mbuf **, int *, int);
-int             carp_iamatch(struct ifnet *, uint8_t *);
+int             carp_iamatch(struct ifnet *);
 int             carp_iamatch6(struct ifnet *);
 struct ifnet   *carp_ourether(void *, u_int8_t *);
 int             carp_output(struct ifnet *, struct mbuf *, struct sockaddr *,

Reply via email to