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 *,