Skip to content

Commit

Permalink
net/hyperv: Add support for promiscuous mode setting
Browse files Browse the repository at this point in the history
Add code to accept promiscuous mode setting, and pass it to
RNDIS filter.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Haiyang Zhang authored and Greg Kroah-Hartman committed Dec 1, 2011
1 parent c181320 commit d426b2e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 25 deletions.
24 changes: 24 additions & 0 deletions drivers/net/hyperv/hyperv_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,27 @@ struct netvsc_device_info {
int ring_size;
};

enum rndis_device_state {
RNDIS_DEV_UNINITIALIZED = 0,
RNDIS_DEV_INITIALIZING,
RNDIS_DEV_INITIALIZED,
RNDIS_DEV_DATAINITIALIZED,
};

struct rndis_device {
struct netvsc_device *net_dev;

enum rndis_device_state state;
bool link_state;
atomic_t new_req_id;

spinlock_t request_lock;
struct list_head req_list;

unsigned char hw_mac_adr[ETH_ALEN];
};


/* Interface */
int netvsc_device_add(struct hv_device *device, void *additional_info);
int netvsc_device_remove(struct hv_device *device);
Expand All @@ -109,6 +130,9 @@ int rndis_filter_receive(struct hv_device *dev,
int rndis_filter_send(struct hv_device *dev,
struct hv_netvsc_packet *pkt);

int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);


#define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF)

#define NVSP_PROTOCOL_VERSION_1 2
Expand Down
46 changes: 43 additions & 3 deletions drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,51 @@ static int ring_size = 128;
module_param(ring_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");

/* no-op so the netdev core doesn't return -EINVAL when modifying the the
* multicast address list in SIOCADDMULTI. hv is setup to get all multicast
* when it calls RndisFilterOnOpen() */
struct set_multicast_work {
struct work_struct work;
struct net_device *net;
};

static void do_set_multicast(struct work_struct *w)
{
struct set_multicast_work *swk =
container_of(w, struct set_multicast_work, work);
struct net_device *net = swk->net;

struct net_device_context *ndevctx = netdev_priv(net);
struct netvsc_device *nvdev;
struct rndis_device *rdev;

nvdev = hv_get_drvdata(ndevctx->device_ctx);
if (nvdev == NULL)
return;

rdev = nvdev->extension;
if (rdev == NULL)
return;

if (net->flags & IFF_PROMISC)
rndis_filter_set_packet_filter(rdev,
NDIS_PACKET_TYPE_PROMISCUOUS);
else
rndis_filter_set_packet_filter(rdev,
NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED);

kfree(w);
}

static void netvsc_set_multicast_list(struct net_device *net)
{
struct set_multicast_work *swk =
kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC);
if (swk == NULL)
return;

swk->net = net;
INIT_WORK(&swk->work, do_set_multicast);
schedule_work(&swk->work);
}

static int netvsc_open(struct net_device *net)
Expand Down
23 changes: 1 addition & 22 deletions drivers/net/hyperv/rndis_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,6 @@
#include "hyperv_net.h"


enum rndis_device_state {
RNDIS_DEV_UNINITIALIZED = 0,
RNDIS_DEV_INITIALIZING,
RNDIS_DEV_INITIALIZED,
RNDIS_DEV_DATAINITIALIZED,
};

struct rndis_device {
struct netvsc_device *net_dev;

enum rndis_device_state state;
bool link_state;
atomic_t new_req_id;

spinlock_t request_lock;
struct list_head req_list;

unsigned char hw_mac_adr[ETH_ALEN];
};

struct rndis_request {
struct list_head list_ent;
struct completion wait_event;
Expand Down Expand Up @@ -522,8 +502,7 @@ static int rndis_filter_query_device_link_status(struct rndis_device *dev)
return ret;
}

static int rndis_filter_set_packet_filter(struct rndis_device *dev,
u32 new_filter)
int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
{
struct rndis_request *request;
struct rndis_set_request *set;
Expand Down

0 comments on commit d426b2e

Please sign in to comment.