diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_bridge.c | 6 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 5 | ||||
-rw-r--r-- | sys/net/if_fddisubr.c | 41 | ||||
-rw-r--r-- | sys/net/if_tokensubr.c | 53 | ||||
-rw-r--r-- | sys/netinet/ip_carp.c | 50 | ||||
-rw-r--r-- | sys/netinet/ip_carp.h | 8 |
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_ */ |