On 19/09/17(Tue) 17:02, Pierre LALET wrote:
> Hi there,
>
> I think I've found a bug in the vxlan_output() function (in
> sys/net/if_vxlan.c). When the encapsulated packet is a multicast (flag
> M_MCAST is set) or a broadcast (flag M_BCAST is set), then
> "encapsulating" packet will have the same flag(s) set when ip_output()
> (or ip6_output()) is called.
>
> This leads to some situations where a broadcast packet (say, an ARP
> who-has request) gets sent in ethernet broacast (but the IP address is
> set to the correct value). Most routers would then drop such a packet.
>
> I have written a Scapy script [1] (see its docstring for more details
> about what it does) to reproduce this bug. For your convenience, I
> have uploaded network captures created with this script, in multicast
> [2] & dynamic [3] modes. In both files, for example, the third packet
> is sent to the ethernet broadcast address, but to the correct IP
> address used for the VXLAN tunnel (239.0.0.1 in my examples). This is
> because the encapsulated packet is a broadcast packet.
>
> I'm not sure if you want to fix that both in vxlan_encap4() and
> vxlan_encap6() (first proposed patch [4]), or in vxlan_output() after
> these calls (second proposed patch [5]).
>
> Please let me know if you need more details from me.
>
> Thanks for your awesome work!
Thanks to you for this great bug report, test and diff.
I'd like to commit your first proposal. Because gif(4) does it like
that and coherency is good. I'd also like to append the following
comment and sync it across multiple pseudo-drivers:
Index: net/if_etherip.c
===================================================================
RCS file: /cvs/src/sys/net/if_etherip.c,v
retrieving revision 1.20
diff -u -p -r1.20 if_etherip.c
--- net/if_etherip.c 9 Oct 2017 08:35:38 -0000 1.20
+++ net/if_etherip.c 9 Oct 2017 12:25:49 -0000
@@ -363,6 +363,10 @@ ip_etherip_output(struct ifnet *ifp, str
return ENETUNREACH;
}
+ /*
+ * Remove multicast and broadcast flags or encapsulated packet
+ * ends up as multicast or broadcast packet.
+ */
m->m_flags &= ~(M_BCAST|M_MCAST);
M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
@@ -520,6 +524,10 @@ ip6_etherip_output(struct ifnet *ifp, st
goto drop;
}
+ /*
+ * Remove multicast and broadcast flags or encapsulated packet
+ * ends up as multicast or broadcast packet.
+ */
m->m_flags &= ~(M_BCAST|M_MCAST);
M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
Index: net/if_gif.c
===================================================================
RCS file: /cvs/src/sys/net/if_gif.c,v
retrieving revision 1.99
diff -u -p -r1.99 if_gif.c
--- net/if_gif.c 11 Aug 2017 21:24:19 -0000 1.99
+++ net/if_gif.c 9 Oct 2017 12:24:53 -0000
@@ -256,6 +256,7 @@ gif_encap(struct ifnet *ifp, struct mbuf
{
struct gif_softc *sc = (struct gif_softc*)ifp;
int error = 0;
+
/*
* Remove multicast and broadcast flags or encapsulated packet
* ends up as multicast or broadcast packet.
Index: net/if_vxlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vxlan.c,v
retrieving revision 1.62
diff -u -p -r1.62 if_vxlan.c
--- net/if_vxlan.c 11 Aug 2017 21:24:19 -0000 1.62
+++ net/if_vxlan.c 9 Oct 2017 12:25:34 -0000
@@ -702,6 +702,12 @@ vxlan_encap4(struct ifnet *ifp, struct m
struct vxlan_softc *sc = (struct vxlan_softc *)ifp->if_softc;
struct ip *ip;
+ /*
+ * Remove multicast and broadcast flags or encapsulated packet
+ * ends up as multicast or broadcast packet.
+ */
+ m->m_flags &= ~(M_MCAST|M_BCAST);
+
M_PREPEND(m, sizeof(*ip), M_DONTWAIT);
if (m == NULL)
return (NULL);
@@ -734,6 +740,12 @@ vxlan_encap6(struct ifnet *ifp, struct m
struct vxlan_softc *sc = (struct vxlan_softc *)ifp->if_softc;
struct ip6_hdr *ip6;
struct in6_addr *in6a;
+
+ /*
+ * Remove multicast and broadcast flags or encapsulated packet
+ * ends up as multicast or broadcast packet.
+ */
+ m->m_flags &= ~(M_MCAST|M_BCAST);
M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
if (m == NULL)