summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_bridge.c6
-rw-r--r--sys/net/if_ethersubr.c5
-rw-r--r--sys/net/if_fddisubr.c41
-rw-r--r--sys/net/if_tokensubr.c53
-rw-r--r--sys/netinet/ip_carp.c50
-rw-r--r--sys/netinet/ip_carp.h8
6 files changed, 135 insertions, 28 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 8936febc198..14c9e41766e 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.139 2004/12/17 12:42:02 pascoe Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.140 2004/12/19 03:25:36 mcbride Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -1395,7 +1395,7 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0
#if NCARP > 0
|| (ifl->ifp->if_carp && carp_ourether(ifl->ifp->if_carp,
- eh, 0) != NULL)
+ eh, IFT_ETHER, 0) != NULL)
#endif
) {
if (srcifl->bif_flags & IFBIF_LEARNING)
@@ -1418,7 +1418,7 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0
#if NCARP > 0
|| (ifl->ifp->if_carp && carp_ourether(ifl->ifp->if_carp,
- eh, 1) != NULL)
+ eh, IFT_ETHER, 1) != NULL)
#endif
) {
m_freem(m);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index cfc6fbc5cc5..c89daabab6e 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.86 2004/12/17 12:42:02 pascoe Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.87 2004/12/19 03:25:36 mcbride Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -677,7 +677,8 @@ ether_input(ifp, eh, m)
#if NCARP > 0
if (ifp->if_carp && ifp->if_type != IFT_CARP &&
- (carp_input(eh, m) == 0))
+ (carp_input(m, (u_int8_t *)&eh->ether_shost,
+ (u_int8_t *)&eh->ether_dhost, eh->ether_type) == 0))
return;
#endif /* NCARP > 0 */
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 3a0f4800ff8..1d9715919c3 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_fddisubr.c,v 1.42 2004/12/10 22:35:17 mcbride Exp $ */
+/* $OpenBSD: if_fddisubr.c,v 1.43 2004/12/19 03:25:36 mcbride Exp $ */
/* $NetBSD: if_fddisubr.c,v 1.5 1996/05/07 23:20:21 christos Exp $ */
/*
@@ -152,8 +152,8 @@ extern struct ifqueue pkintrq;
* Assumes that ifp is actually pointer to arpcom structure.
*/
int
-fddi_output(ifp, m0, dst, rt0)
- struct ifnet *ifp;
+fddi_output(ifp0, m0, dst, rt0)
+ struct ifnet *ifp0;
struct mbuf *m0;
struct sockaddr *dst;
struct rtentry *rt0;
@@ -165,9 +165,28 @@ fddi_output(ifp, m0, dst, rt0)
struct rtentry *rt;
struct mbuf *mcopy = (struct mbuf *)0;
struct fddi_header *fh;
- struct arpcom *ac = (struct arpcom *)ifp;
+ struct arpcom *ac = (struct arpcom *)ifp0;
short mflags;
+ struct ifnet *ifp = ifp0;
+
+#if NCARP > 0
+ if (ifp->if_type == IFT_CARP) {
+ struct ifaddr *ifa;
+ /* loop back if this is going to the carp interface */
+ if (dst != NULL && ifp0->if_link_state == LINK_STATE_UP &&
+ (ifa = ifa_ifwithaddr(dst)) != NULL &&
+ ifa->ifa_ifp == ifp0)
+ return (looutput(ifp0, m, dst, rt0));
+
+ ifp = ifp->if_carpdev;
+ ac = (struct arpcom *)ifp;
+
+ if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
+ (IFF_UP|IFF_RUNNING))
+ senderr(ENETDOWN);
+ }
+#endif /* NCARP > 0 */
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
if ((rt = rt0) != NULL) {
@@ -396,7 +415,7 @@ fddi_output(ifp, m0, dst, rt0)
sizeof(fh->fddi_shost));
#if NCARP > 0
if (ifp->if_carp) {
- error = carp_fix_lladdr(ifp, m, NULL, NULL);
+ error = carp_fix_lladdr(ifp0, m, dst, NULL);
if (error)
goto bad;
}
@@ -415,6 +434,10 @@ fddi_output(ifp, m0, dst, rt0)
return (error);
}
ifp->if_obytes += len;
+#if NCARP > 0
+ if (ifp != ifp0)
+ ifp0->if_obytes += len;
+#endif /* NCARP > 0 */
if (mflags & M_MCAST)
ifp->if_omcasts++;
if ((ifp->if_flags & IFF_OACTIVE) == 0)
@@ -468,6 +491,14 @@ fddi_input(ifp, fh, m)
goto dropanyway;
etype = ntohs(l->llc_snap.ether_type);
m_adj(m, LLC_SNAPFRAMELEN);
+
+#if NCARP > 0
+ if (ifp->if_carp && ifp->if_type != IFT_CARP &&
+ (carp_input(m, (u_int8_t *)&fh->fddi_shost,
+ (u_int8_t *)&fh->fddi_dhost, l->llc_snap.ether_type) == 0))
+ return;
+#endif
+
switch (etype) {
#ifdef INET
case ETHERTYPE_IP:
diff --git a/sys/net/if_tokensubr.c b/sys/net/if_tokensubr.c
index 74077d9c467..e815b80ed9a 100644
--- a/sys/net/if_tokensubr.c
+++ b/sys/net/if_tokensubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tokensubr.c,v 1.16 2004/07/16 15:01:09 henning Exp $ */
+/* $OpenBSD: if_tokensubr.c,v 1.17 2004/12/19 03:25:36 mcbride Exp $ */
/* $NetBSD: if_tokensubr.c,v 1.7 1999/05/30 00:39:07 bad Exp $ */
/*
@@ -75,6 +75,11 @@
#include "bpfilter.h"
+#include "carp.h"
+#if NCARP > 0
+#include <netinet/ip_carp.h>
+#endif
+
#ifdef LLC
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
@@ -122,8 +127,8 @@ int token_output(struct ifnet *, struct mbuf *, struct sockaddr *,
* XXX route info has to go into the same mbuf as the header
*/
int
-token_output(ifp, m0, dst, rt0)
- struct ifnet *ifp;
+token_output(ifp0, m0, dst, rt0)
+ struct ifnet *ifp0;
struct mbuf *m0;
struct sockaddr *dst;
struct rtentry *rt0;
@@ -136,12 +141,32 @@ token_output(ifp, m0, dst, rt0)
struct mbuf *mcopy = (struct mbuf *)0;
struct token_header *trh;
#ifdef INET
- struct arpcom *ac = (struct arpcom *)ifp;
+ struct arpcom *ac = (struct arpcom *)ifp0;
#endif /* INET */
struct token_rif *rif = (struct token_rif *)0;
struct token_rif bcastrif;
size_t riflen = 0;
short mflags;
+ struct ifnet *ifp = ifp0;
+
+#if NCARP > 0
+ if (ifp->if_type == IFT_CARP) {
+ struct ifaddr *ifa;
+
+ /* loop back if this is going to the carp interface */
+ if (dst != NULL && ifp0->if_link_state == LINK_STATE_UP &&
+ (ifa = ifa_ifwithaddr(dst)) != NULL &&
+ ifa->ifa_ifp == ifp0)
+ return (looutput(ifp0, m, dst, rt0));
+
+ ifp = ifp->if_carpdev;
+ ac = (struct arpcom *)ifp;
+
+ if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
+ (IFF_UP|IFF_RUNNING))
+ senderr(ENETDOWN);
+ }
+#endif /* NCARP > 0 */
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
@@ -384,6 +409,14 @@ token_output(ifp, m0, dst, rt0)
#if 0
send:
#endif /* 0 */
+#if NCARP > 0
+ if (ifp->if_carp) {
+ error = carp_fix_lladdr(ifp0, m, dst, NULL);
+ if (error)
+ goto bad;
+ }
+#endif
+
mflags = m->m_flags;
len = m->m_pkthdr.len;
@@ -399,6 +432,10 @@ send:
return (error);
}
ifp->if_obytes += len;
+#if NCARP > 0
+ if (ifp != ifp0)
+ ifp0->if_obytes += len;
+#endif /* NCARP > 0 */
if (mflags & M_MCAST)
ifp->if_omcasts++;
if ((ifp->if_flags & IFF_OACTIVE) == 0)
@@ -467,6 +504,14 @@ token_input(ifp, m)
goto dropanyway;
etype = ntohs(l->llc_snap.ether_type);
m_adj(m, LLC_SNAPFRAMELEN);
+
+#if NCARP > 0
+ if (ifp->if_carp && ifp->if_type != IFT_CARP &&
+ (carp_input(m, (u_int8_t *)&th->token_shost,
+ (u_int8_t *)&th->token_dhost, l->llc_snap.ether_type) == 0))
+ return;
+#endif
+
switch (etype) {
#ifdef INET
case ETHERTYPE_IP:
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 500a76b8d77..cb265069aea 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.85 2004/12/18 00:52:21 pascoe Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.86 2004/12/19 03:25:37 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -718,15 +718,15 @@ carp_clone_create(ifc, unit)
unit);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | IFF_NOARP;
ifp->if_ioctl = carp_ioctl;
- ifp->if_output = ether_output;
ifp->if_start = carp_start;
+ ifp->if_output = carp_output;
ifp->if_type = IFT_CARP;
ifp->if_addrlen = ETHER_ADDR_LEN;
ifp->if_hdrlen = ETHER_HDR_LEN;
ifp->if_mtu = ETHERMTU;
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
IFQ_SET_READY(&ifp->if_snd);
- if_attachhead(ifp);
+ if_attach(ifp);
if_alloc_sadl(ifp);
carp_set_enaddr(sc);
@@ -1249,7 +1249,7 @@ carp_macmatch6(void *v, struct mbuf *m, struct in6_addr *taddr)
#endif /* INET6 */
struct ifnet *
-carp_ourether(void *v, struct ether_header *eh, int src)
+carp_ourether(void *v, struct ether_header *eh, u_char iftype, int src)
{
struct carp_if *cif = (struct carp_if *)v;
struct carp_softc *vh;
@@ -1260,8 +1260,20 @@ carp_ourether(void *v, struct ether_header *eh, int src)
else
ena = (u_int8_t *)&eh->ether_dhost;
- if (ena[0] || ena[1] || ena[2] != 0x5e || ena[3] || ena[4] != 1)
+ switch (iftype) {
+ case IFT_ETHER:
+ case IFT_FDDI:
+ if (ena[0] || ena[1] || ena[2] != 0x5e || ena[3] || ena[4] != 1)
+ return (NULL);
+ break;
+ case IFT_ISO88025:
+ if (ena[0] != 3 || ena[1] || ena[4] || ena[5])
+ return (NULL);
+ break;
+ default:
return (NULL);
+ break;
+ }
TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list)
if ((vh->sc_ac.ac_if.if_flags & (IFF_UP|IFF_RUNNING)) ==
@@ -1274,12 +1286,17 @@ carp_ourether(void *v, struct ether_header *eh, int src)
}
int
-carp_input(struct ether_header *eh, struct mbuf *m)
+carp_input(struct mbuf *m, u_int8_t *shost, u_int8_t *dhost, u_int16_t etype)
{
+ struct ether_header eh;
struct carp_if *cif = (struct carp_if *)m->m_pkthdr.rcvif->if_carp;
struct ifnet *ifp;
- if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ bcopy(shost, &eh.ether_shost, sizeof(eh.ether_shost));
+ bcopy(dhost, &eh.ether_dhost, sizeof(eh.ether_dhost));
+ eh.ether_type = etype;
+
+ if (m->m_flags & (M_BCAST|M_MCAST)) {
struct carp_softc *vh;
struct mbuf *m0;
@@ -1292,12 +1309,12 @@ carp_input(struct ether_header *eh, struct mbuf *m)
if (m0 == NULL)
continue;
m0->m_pkthdr.rcvif = &vh->sc_ac.ac_if;
- ether_input(&vh->sc_ac.ac_if, eh, m0);
+ ether_input(&vh->sc_ac.ac_if, &eh, m0);
}
return (1);
}
- ifp = carp_ourether(cif, eh, 0);
+ ifp = carp_ourether(cif, &eh, m->m_pkthdr.rcvif->if_type, 0);
if (ifp == NULL)
return (1);
@@ -1316,12 +1333,12 @@ carp_input(struct ether_header *eh, struct mbuf *m)
m0.m_flags = 0;
m0.m_next = m;
m0.m_len = ETHER_HDR_LEN;
- m0.m_data = (char *)eh;
+ m0.m_data = (char *)&eh;
bpf_mtap(ifp->if_bpf, &m0);
}
#endif
ifp->if_ipackets++;
- ether_input(ifp, eh, m);
+ ether_input(ifp, &eh, m);
return (0);
}
@@ -1976,6 +1993,17 @@ carp_start(struct ifnet *ifp)
}
int
+carp_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
+ struct rtentry *rt)
+{
+ struct ifnet *ifp0 = ((struct carp_softc *)ifp->if_softc)->sc_carpdev;
+ if (ifp0)
+ return (ifp0->if_output(ifp, m, sa, rt));
+ else
+ return (EINVAL);
+}
+
+int
carp_fix_lladdr(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
struct rtentry *rt)
{
diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h
index 879e6f1cab6..452afb05c4d 100644
--- a/sys/netinet/ip_carp.h
+++ b/sys/netinet/ip_carp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.h,v 1.14 2004/12/17 12:42:01 pascoe Exp $ */
+/* $OpenBSD: ip_carp.h,v 1.15 2004/12/19 03:25:37 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -162,8 +162,10 @@ int carp_iamatch(void *, struct in_ifaddr *, struct in_addr *,
u_int8_t **);
struct ifaddr *carp_iamatch6(void *, struct in6_addr *);
void *carp_macmatch6(void *, struct mbuf *, struct in6_addr *);
-struct ifnet *carp_ourether(void *, struct ether_header *, int);
-int carp_input(struct ether_header *, struct mbuf *);
+struct ifnet *carp_ourether(void *, struct ether_header *, u_char, int);
+int carp_input(struct mbuf *, u_int8_t *, u_int8_t *, u_int16_t);
+int carp_output(struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *);
int carp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
#endif /* _KERNEL */
#endif /* _NETINET_IP_CARP_H_ */