On 05/28/17 16:09, Martin Pieuchot wrote:
> On 28/05/17(Sun) 16:02, Florian Riehm wrote:
>> [...]
>> Ok, new diff below.
>
> I overlooked something! See below:
Good catch!
I also forgot SRPL_LEAVE.
fixed.
Index: share/man/man9/mbuf_tags.9
===================================================================
RCS file: /cvs/src/share/man/man9/mbuf_tags.9,v
retrieving revision 1.37
diff -u -p -r1.37 mbuf_tags.9
--- share/man/man9/mbuf_tags.9 24 Nov 2015 19:58:48 -0000 1.37
+++ share/man/man9/mbuf_tags.9 28 May 2017 15:16:09 -0000
@@ -170,6 +170,13 @@ Used by the IPv4 stack to keep track of
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
Index: sys/netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.310
diff -u -p -r1.310 ip_carp.c
--- sys/netinet/ip_carp.c 27 May 2017 21:55:52 -0000 1.310
+++ sys/netinet/ip_carp.c 28 May 2017 15:16:10 -0000
@@ -1422,8 +1422,25 @@ carp_input(struct ifnet *ifp0, struct mb
(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) {
@@ -1456,27 +1473,23 @@ carp_input(struct ifnet *ifp0, struct mb
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);
@@ -1484,6 +1497,25 @@ carp_lsdrop(struct mbuf *m, sa_family_t
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?
Index: sys/netinet/ip_carp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.h,v
retrieving revision 1.42
diff -u -p -r1.42 ip_carp.h
--- sys/netinet/ip_carp.h 14 Apr 2017 20:46:31 -0000 1.42
+++ sys/netinet/ip_carp.h 28 May 2017 15:16:10 -0000
@@ -204,6 +204,7 @@ struct ifnet *carp_ourether(void *, u_in
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_ */
Index: sys/netinet/ip_icmp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.168
diff -u -p -r1.168 ip_icmp.c
--- sys/netinet/ip_icmp.c 22 May 2017 14:26:08 -0000 1.168
+++ sys/netinet/ip_icmp.c 28 May 2017 15:16:10 -0000
@@ -498,7 +498,7 @@ icmp_input_if(struct ifnet *ifp, struct
#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
/*
@@ -582,7 +582,7 @@ reflect:
#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 */
@@ -650,7 +650,7 @@ reflect:
#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),
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.304
diff -u -p -r1.304 ip_input.c
--- sys/netinet/ip_input.c 22 May 2017 22:23:11 -0000 1.304
+++ sys/netinet/ip_input.c 28 May 2017 15:16:10 -0000
@@ -319,8 +319,9 @@ ipv4_input(struct mbuf *m)
}
#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
@@ -427,7 +428,7 @@ ipv4_input(struct mbuf *m)
#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
/*
Index: sys/netinet6/icmp6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/icmp6.c,v
retrieving revision 1.210
diff -u -p -r1.210 icmp6.c
--- sys/netinet6/icmp6.c 8 May 2017 16:14:47 -0000 1.210
+++ sys/netinet6/icmp6.c 28 May 2017 15:16:10 -0000
@@ -446,7 +446,7 @@ icmp6_input(struct mbuf **mp, int *offp,
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;
}
Index: sys/netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.189
diff -u -p -r1.189 ip6_input.c
--- sys/netinet6/ip6_input.c 23 May 2017 08:13:10 -0000 1.189
+++ sys/netinet6/ip6_input.c 28 May 2017 15:16:10 -0000
@@ -207,9 +207,9 @@ ip6_input(struct mbuf *m)
}
#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);
@@ -448,7 +448,7 @@ ip6_input(struct mbuf *m)
#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
/*
Index: sys/sys/mbuf.h
===================================================================
RCS file: /cvs/src/sys/sys/mbuf.h,v
retrieving revision 1.228
diff -u -p -r1.228 mbuf.h
--- sys/sys/mbuf.h 16 May 2017 15:57:03 -0000 1.228
+++ sys/sys/mbuf.h 28 May 2017 15:16:10 -0000
@@ -485,11 +485,12 @@ struct m_tag *m_tag_next(struct mbuf *,
#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).