On 28/05/17(Sun) 17:22, Florian Riehm wrote:
> 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.
ok mpi@
> 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).