diff options
author | 2004-12-07 20:38:46 +0000 | |
---|---|---|
committer | 2004-12-07 20:38:46 +0000 | |
commit | f8e109fa9051a27bf395da41c947e331d5ad2de7 (patch) | |
tree | 7de984f01c1082a614443c140651c6c344d7b742 /sys/net | |
parent | KNF (diff) | |
download | wireguard-openbsd-f8e109fa9051a27bf395da41c947e331d5ad2de7.tar.xz wireguard-openbsd-f8e109fa9051a27bf395da41c947e331d5ad2de7.zip |
Convert carp(4) to behave more like a regular interface, much in the same
style as vlan(4). carp interfaces no longer require the physical interface
to be on the same subnet as the carp interface, or even that the physical
interface has an adress at all, so CARP can now be used on /30 networks.
ok deraadt@ henning@
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 5 | ||||
-rw-r--r-- | sys/net/if.h | 9 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 40 |
3 files changed, 42 insertions, 12 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index b939426d910..7ab0472ce97 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.96 2004/12/07 19:26:46 mcbride Exp $ */ +/* $OpenBSD: if.c,v 1.97 2004/12/07 20:38:46 mcbride Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -79,6 +79,7 @@ #include <net/if.h> #include <net/if_dl.h> +#include <net/if_types.h> #include <net/route.h> #ifdef INET @@ -487,7 +488,7 @@ if_detach(ifp) #if NCARP > 0 /* Remove the interface from any carp group it is a part of. */ - if (ifp->if_carp) + if (ifp->if_carp && ifp->if_type != IFT_CARP) carp_ifdetach(ifp); #endif diff --git a/sys/net/if.h b/sys/net/if.h index 7c777339863..64be1d6b9e5 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.61 2004/12/07 19:26:46 mcbride Exp $ */ +/* $OpenBSD: if.h,v 1.62 2004/12/07 20:38:46 mcbride Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -180,7 +180,12 @@ struct ifnet { /* and the entries */ int if_pcount; /* number of promiscuous listeners */ caddr_t if_bpf; /* packet filter structure */ caddr_t if_bridge; /* bridge structure */ - caddr_t if_carp; /* carp structure */ + union { + caddr_t carp_s; /* carp structure (used by !carp ifs) */ + struct ifnet *carp_d; /* ptr to carpdev (used by carp ifs) */ + } if_carp_ptr; +#define if_carp if_carp_ptr.carp_s +#define if_carpdev if_carp_ptr.carp_d u_short if_index; /* numeric abbreviation for this if */ short if_timer; /* time 'til if_watchdog called */ short if_flags; /* up/down, broadcast, etc. */ diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index a10d0467d29..2dbce582d7c 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.82 2004/12/07 19:26:46 mcbride Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.83 2004/12/07 20:38:46 mcbride Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -239,8 +239,8 @@ ether_ioctl(ifp, arp, cmd, data) * Assumes that ifp is actually pointer to arpcom structure. */ int -ether_output(ifp, m0, dst, rt0) - struct ifnet *ifp; +ether_output(ifp0, m0, dst, rt0) + struct ifnet *ifp0; struct mbuf *m0; struct sockaddr *dst; struct rtentry *rt0; @@ -252,8 +252,28 @@ ether_output(ifp, m0, dst, rt0) struct rtentry *rt; struct mbuf *mcopy = (struct mbuf *)0; struct ether_header *eh; - 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); @@ -517,7 +537,7 @@ ether_output(ifp, m0, dst, rt0) #if NCARP > 0 if (ifp->if_carp) { int error; - error = carp_output(ifp, m, dst, NULL); + error = carp_output(ifp0, m, dst, NULL); if (error) goto bad; } @@ -537,6 +557,10 @@ ether_output(ifp, m0, dst, rt0) return (error); } ifp->if_obytes += len + ETHER_HDR_LEN; +#if NCARP > 0 + if (ifp != ifp0) + ifp0->if_obytes += len + ETHER_HDR_LEN; +#endif /* NCARP > 0 */ if (mflags & M_MCAST) ifp->if_omcasts++; if ((ifp->if_flags & IFF_OACTIVE) == 0) @@ -653,9 +677,9 @@ ether_input(ifp, eh, m) #endif /* NVLAN > 0 */ #if NCARP > 0 - if (ifp->if_carp && - carp_forus(ifp->if_carp, eh->ether_dhost)) - goto decapsulate; + if (ifp->if_carp && ifp->if_type != IFT_CARP && + (carp_input(eh, m) == 0)) + return; #endif /* NCARP > 0 */ ac = (struct arpcom *)ifp; |