-.\" $OpenBSD: mbuf_tags.9,v 1.37 2015/11/24 19:58:48 jmc Exp $
+.\" $OpenBSD: mbuf_tags.9,v 1.38 2017/05/30 12:09:27 friehm Exp $
.\"
.\" The author of this man page is Angelos D. Keromytis (angelos@cis.upenn.edu)
.\"
.\" MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
.\" PURPOSE.
.\"
-.Dd $Mdocdate: November 24 2015 $
+.Dd $Mdocdate: May 30 2017 $
.Dt M_TAG_GET 9
.Os
.Sh NAME
IP packet, in case a protocol wants to respond over the same route.
The tag contains a
.Va struct ip_srcrt .
+.It PACKET_TAG_CARP_BAL_IP
+Used by
+.Xr carp 4
+to mark packets received in mode
+.Va balancing ip .
+This packets need some special treatment since they contain layer 3 unicast
+inside layer 2 multicast. The tag contains no data.
.El
.Pp
.Fn m_tag_find
-/* $OpenBSD: ip_carp.c,v 1.311 2017/05/28 12:47:24 mpi Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.312 2017/05/30 12:09:27 friehm Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
(IFF_UP|IFF_RUNNING))
continue;
- if (carp_vhe_match(sc, eh->ether_dhost))
+ if (carp_vhe_match(sc, eh->ether_dhost)) {
+ /*
+ * These packets look like layer 2 multicast but they
+ * are unicast at layer 3. With help of the tag the
+ * mbuf's M_MCAST flag can be removed by carp_lsdrop()
+ * after we have passed layer 2.
+ */
+ if (sc->sc_balancing == CARP_BAL_IP) {
+ struct m_tag *mtag;
+ mtag = m_tag_get(PACKET_TAG_CARP_BAL_IP, 0,
+ M_NOWAIT);
+ if (mtag == NULL) {
+ m_freem(m);
+ goto out;
+ }
+ m_tag_prepend(m, mtag);
+ }
break;
+ }
}
if (sc == NULL) {
return (0);
}
- /*
- * Clear mcast if received on a carp IP balanced address.
- */
- if (sc->sc_balancing == CARP_BAL_IP &&
- ETHER_IS_MULTICAST(eh->ether_dhost))
- *(eh->ether_dhost) &= ~0x01;
-
ml_enqueue(&ml, m);
if_input(&sc->sc_if, &ml);
+out:
SRPL_LEAVE(&sr);
return (1);
}
int
-carp_lsdrop(struct mbuf *m, sa_family_t af, u_int32_t *src, u_int32_t *dst)
+carp_lsdrop(struct mbuf *m, sa_family_t af, u_int32_t *src, u_int32_t *dst,
+ int drop)
{
struct ifnet *ifp;
struct carp_softc *sc;
int match = 1;
u_int32_t fold;
+ struct m_tag *mtag;
ifp = if_get(m->m_pkthdr.ph_ifidx);
KASSERT(ifp != NULL);
sc = ifp->if_softc;
if (sc->sc_balancing == CARP_BAL_NONE)
goto done;
+
+ /*
+ * Remove M_MCAST flag from mbuf of balancing ip traffic, since the fact
+ * that it is layer 2 multicast does not implicate that it is also layer
+ * 3 multicast.
+ */
+ if (m->m_flags & M_MCAST &&
+ (mtag = m_tag_find(m, PACKET_TAG_CARP_BAL_IP, NULL))) {
+ m_tag_delete(m, mtag);
+ m->m_flags &= ~M_MCAST;
+ }
+
+ /*
+ * Return without making a drop decision. This allows to clear the
+ * M_MCAST flag and do nothing else.
+ */
+ if (!drop)
+ goto done;
+
/*
* Never drop carp advertisements.
* XXX Bad idea to pass all broadcast / multicast traffic?
-/* $OpenBSD: ip_carp.h,v 1.42 2017/04/14 20:46:31 bluhm Exp $ */
+/* $OpenBSD: ip_carp.h,v 1.43 2017/05/30 12:09:27 friehm Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
int carp_output(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
int carp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int carp_lsdrop(struct mbuf *, sa_family_t, u_int32_t *, u_int32_t *);
+int carp_lsdrop(struct mbuf *, sa_family_t, u_int32_t *,
+ u_int32_t *, int);
#endif /* _KERNEL */
#endif /* _NETINET_IP_CARP_H_ */
-/* $OpenBSD: ip_icmp.c,v 1.168 2017/05/22 14:26:08 bluhm Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.169 2017/05/30 12:09:27 friehm Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
#if NCARP > 0
if (ifp->if_type == IFT_CARP &&
carp_lsdrop(m, AF_INET, &sin.sin_addr.s_addr,
- &ip->ip_dst.s_addr))
+ &ip->ip_dst.s_addr, 1))
goto freeit;
#endif
/*
#if NCARP > 0
if (ifp->if_type == IFT_CARP &&
carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr,
- &ip->ip_dst.s_addr))
+ &ip->ip_dst.s_addr, 1))
goto freeit;
#endif
/* Free packet atttributes */
#if NCARP > 0
if (ifp->if_type == IFT_CARP &&
carp_lsdrop(m, AF_INET, &sdst.sin_addr.s_addr,
- &ip->ip_dst.s_addr))
+ &ip->ip_dst.s_addr, 1))
goto freeit;
#endif
rtredirect(sintosa(&sdst), sintosa(&sgw),
-/* $OpenBSD: ip_input.c,v 1.308 2017/05/30 07:50:37 mpi Exp $ */
+/* $OpenBSD: ip_input.c,v 1.309 2017/05/30 12:09:27 friehm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
}
#if NCARP > 0
- if (ifp->if_type == IFT_CARP && ip->ip_p != IPPROTO_ICMP &&
- carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr, &ip->ip_dst.s_addr))
+ if (ifp->if_type == IFT_CARP &&
+ carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr, &ip->ip_dst.s_addr,
+ (ip->ip_p == IPPROTO_ICMP ? 0 : 1)))
goto bad;
#endif
#if NCARP > 0
if (ifp->if_type == IFT_CARP && ip->ip_p == IPPROTO_ICMP &&
- carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr, &ip->ip_dst.s_addr))
+ carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr, &ip->ip_dst.s_addr, 1))
goto bad;
#endif
/*
-/* $OpenBSD: icmp6.c,v 1.210 2017/05/08 16:14:47 rzalamena Exp $ */
+/* $OpenBSD: icmp6.c,v 1.211 2017/05/30 12:09:27 friehm Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
if (ifp->if_type == IFT_CARP &&
icmp6->icmp6_type == ICMP6_ECHO_REQUEST &&
carp_lsdrop(m, AF_INET6, ip6->ip6_src.s6_addr32,
- ip6->ip6_dst.s6_addr32)) {
+ ip6->ip6_dst.s6_addr32, 1)) {
if_put(ifp);
goto freeit;
}
-/* $OpenBSD: ip6_input.c,v 1.192 2017/05/30 07:50:37 mpi Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.193 2017/05/30 12:09:27 friehm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
}
#if NCARP > 0
- if (ifp->if_type == IFT_CARP && ip6->ip6_nxt != IPPROTO_ICMPV6 &&
+ if (ifp->if_type == IFT_CARP &&
carp_lsdrop(m, AF_INET6, ip6->ip6_src.s6_addr32,
- ip6->ip6_dst.s6_addr32))
+ ip6->ip6_dst.s6_addr32, (ip6->ip6_nxt == IPPROTO_ICMPV6 ? 0 : 1)))
goto bad;
#endif
ip6stat_inc(ip6s_nxthist + ip6->ip6_nxt);
#if NCARP > 0
if (ifp->if_type == IFT_CARP && ip6->ip6_nxt == IPPROTO_ICMPV6 &&
carp_lsdrop(m, AF_INET6, ip6->ip6_src.s6_addr32,
- ip6->ip6_dst.s6_addr32))
+ ip6->ip6_dst.s6_addr32, 1))
goto bad;
#endif
/*
-/* $OpenBSD: mbuf.h,v 1.228 2017/05/16 15:57:03 kettenis Exp $ */
+/* $OpenBSD: mbuf.h,v 1.229 2017/05/30 12:09:27 friehm Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
#define PACKET_TAG_PF_REASSEMBLED 0x0800 /* pf reassembled ipv6 packet */
#define PACKET_TAG_SRCROUTE 0x1000 /* IPv4 source routing options */
#define PACKET_TAG_TUNNEL 0x2000 /* Tunnel endpoint address */
+#define PACKET_TAG_CARP_BAL_IP 0x4000 /* carp(4) ip balanced marker */
#define MTAG_BITS \
("\20\1IPSEC_IN_DONE\2IPSEC_OUT_DONE\3IPSEC_IN_CRYPTO_DONE" \
"\4IPSEC_OUT_CRYPTO_NEEDED\5IPSEC_PENDING_TDB\6BRIDGE\7GIF\10GRE\11DLT" \
- "\12PF_DIVERT\14PF_REASSEMBLED\15SRCROUTE\16TUNNEL")
+ "\12PF_DIVERT\14PF_REASSEMBLED\15SRCROUTE\16TUNNEL\17CARP_BAL_IP")
/*
* Maximum tag payload length (that is excluding the m_tag structure).