Hi,

A user has reported an issue with not having a proper promiscuous mode
on reddit a while back but as of now didn't manage to test the diff.

If somebody is running OpenBSD on Hyper-V, please test the diff below
and see if there are any regressions (like increased CPU load) without
running tcpdump and then try running 'tcpdump -nvvi hvn0' and see if
that works: one indicator is the PROMISC flag in the ifconfig output
that should get set when tcpdump is started and cleared once it's
finished.

I'm not certain if Hyper-V will allow you to sniff a whole lot of
traffic on the virtual switch, however, one of the goals here is to
instruct RNDIS to enter "all multicast capture" mode when one or more
multicast addresses are configured.  Therefore one of the goals is to
attempt to support CARP operation on the virtual switch.


commit 6e6b001dae79505e3e0fbca663c31f9eb6da285b
Author: Mike Belopuhov <m...@belopuhov.com>
Date:   Sun Mar 11 13:38:21 2018 +0100

    Add support for promisc mode

diff --git sys/dev/pv/if_hvn.c sys/dev/pv/if_hvn.c
index 3ca35165565..6d5e919b01c 100644
--- sys/dev/pv/if_hvn.c
+++ sys/dev/pv/if_hvn.c
@@ -134,11 +134,10 @@ struct hvn_softc {
        bus_dma_tag_t                    sc_dmat;
 
        struct arpcom                    sc_ac;
        struct ifmedia                   sc_media;
        int                              sc_link_state;
-       int                              sc_promisc;
 
        /* NVS protocol */
        int                              sc_proto;
        uint32_t                         sc_nvstid;
        uint8_t                          sc_nvsrsp[HVN_NVS_MSGSIZE];
@@ -208,11 +207,10 @@ void      hvn_rxeof(struct hvn_softc *, caddr_t, 
uint32_t, struct mbuf_list *);
 void   hvn_rndis_complete(struct hvn_softc *, caddr_t, uint32_t);
 int    hvn_rndis_output(struct hvn_softc *, struct hvn_tx_desc *);
 void   hvn_rndis_status(struct hvn_softc *, caddr_t, uint32_t);
 int    hvn_rndis_query(struct hvn_softc *, uint32_t, void *, size_t *);
 int    hvn_rndis_set(struct hvn_softc *, uint32_t, void *, size_t);
-int    hvn_rndis_open(struct hvn_softc *);
 int    hvn_rndis_close(struct hvn_softc *);
 void   hvn_rndis_detach(struct hvn_softc *);
 
 struct cfdriver hvn_cd = {
        NULL, "hvn", DV_IFNET
@@ -401,26 +399,44 @@ hvn_link_status(struct hvn_softc *sc)
 }
 
 int
 hvn_iff(struct hvn_softc *sc)
 {
-       /* XXX */
-       sc->sc_promisc = 0;
+       struct ifnet *ifp = &sc->sc_ac.ac_if;
+       uint32_t filter = 0;
+       int rv;
 
-       return (0);
+       ifp->if_flags &= ~IFF_ALLMULTI;
+
+       if ((ifp->if_flags & IFF_PROMISC) || sc->sc_ac.ac_multirangecnt > 0) {
+               ifp->if_flags |= IFF_ALLMULTI;
+               filter = NDIS_PACKET_TYPE_PROMISCUOUS;
+       } else {
+               filter = NDIS_PACKET_TYPE_BROADCAST |
+                   NDIS_PACKET_TYPE_DIRECTED;
+               if (sc->sc_ac.ac_multicnt > 0) {
+                       ifp->if_flags |= IFF_ALLMULTI;
+                       filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+               }
+       }
+
+       rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
+           &filter, sizeof(filter));
+       if (rv)
+               DPRINTF("%s: failed to set RNDIS filter to %#x\n",
+                   sc->sc_dev.dv_xname, filter);
+       return (rv);
 }
 
 void
 hvn_init(struct hvn_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ac.ac_if;
 
        hvn_stop(sc);
 
-       hvn_iff(sc);
-
-       if (hvn_rndis_open(sc) == 0) {
+       if (hvn_iff(sc) == 0) {
                ifp->if_flags |= IFF_RUNNING;
                ifq_clr_oactive(&ifp->if_snd);
        }
 }
 
@@ -1723,31 +1739,10 @@ hvn_rndis_set(struct hvn_softc *sc, uint32_t oid, void 
*data, size_t length)
        hvn_free_cmd(sc, rc);
 
        return (rv);
 }
 
-int
-hvn_rndis_open(struct hvn_softc *sc)
-{
-       uint32_t filter;
-       int rv;
-
-       if (sc->sc_promisc)
-               filter = NDIS_PACKET_TYPE_PROMISCUOUS;
-       else
-               filter = NDIS_PACKET_TYPE_BROADCAST |
-                   NDIS_PACKET_TYPE_ALL_MULTICAST |
-                   NDIS_PACKET_TYPE_DIRECTED;
-
-       rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
-           &filter, sizeof(filter));
-       if (rv)
-               DPRINTF("%s: failed to set RNDIS filter to %#x\n",
-                   sc->sc_dev.dv_xname, filter);
-       return (rv);
-}
-
 int
 hvn_rndis_close(struct hvn_softc *sc)
 {
        uint32_t filter = 0;
        int rv;

Reply via email to