diff options
author | Haiyang Zhang <haiyangz@microsoft.com> | 2011-11-30 10:19:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-01 13:25:26 -0500 |
commit | d426b2e3d91f8ec3203f8852e7ad0153b5dfdf71 (patch) | |
tree | 331e51d5ef01679b32ab28e2832eeedc8a9b23bc /drivers/net/hyperv/netvsc_drv.c | |
parent | c18132005e711c07523d8c6602e5b2266ab9a0f2 (diff) |
net/hyperv: Add support for promiscuous mode setting
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>
Diffstat (limited to 'drivers/net/hyperv/netvsc_drv.c')
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 93b0e91cbf98..b69c3a4d1e9e 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -56,11 +56,51 @@ static int ring_size = 128; | |||
56 | module_param(ring_size, int, S_IRUGO); | 56 | module_param(ring_size, int, S_IRUGO); |
57 | MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); | 57 | MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); |
58 | 58 | ||
59 | /* no-op so the netdev core doesn't return -EINVAL when modifying the the | 59 | struct set_multicast_work { |
60 | * multicast address list in SIOCADDMULTI. hv is setup to get all multicast | 60 | struct work_struct work; |
61 | * when it calls RndisFilterOnOpen() */ | 61 | struct net_device *net; |
62 | }; | ||
63 | |||
64 | static void do_set_multicast(struct work_struct *w) | ||
65 | { | ||
66 | struct set_multicast_work *swk = | ||
67 | container_of(w, struct set_multicast_work, work); | ||
68 | struct net_device *net = swk->net; | ||
69 | |||
70 | struct net_device_context *ndevctx = netdev_priv(net); | ||
71 | struct netvsc_device *nvdev; | ||
72 | struct rndis_device *rdev; | ||
73 | |||
74 | nvdev = hv_get_drvdata(ndevctx->device_ctx); | ||
75 | if (nvdev == NULL) | ||
76 | return; | ||
77 | |||
78 | rdev = nvdev->extension; | ||
79 | if (rdev == NULL) | ||
80 | return; | ||
81 | |||
82 | if (net->flags & IFF_PROMISC) | ||
83 | rndis_filter_set_packet_filter(rdev, | ||
84 | NDIS_PACKET_TYPE_PROMISCUOUS); | ||
85 | else | ||
86 | rndis_filter_set_packet_filter(rdev, | ||
87 | NDIS_PACKET_TYPE_BROADCAST | | ||
88 | NDIS_PACKET_TYPE_ALL_MULTICAST | | ||
89 | NDIS_PACKET_TYPE_DIRECTED); | ||
90 | |||
91 | kfree(w); | ||
92 | } | ||
93 | |||
62 | static void netvsc_set_multicast_list(struct net_device *net) | 94 | static void netvsc_set_multicast_list(struct net_device *net) |
63 | { | 95 | { |
96 | struct set_multicast_work *swk = | ||
97 | kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); | ||
98 | if (swk == NULL) | ||
99 | return; | ||
100 | |||
101 | swk->net = net; | ||
102 | INIT_WORK(&swk->work, do_set_multicast); | ||
103 | schedule_work(&swk->work); | ||
64 | } | 104 | } |
65 | 105 | ||
66 | static int netvsc_open(struct net_device *net) | 106 | static int netvsc_open(struct net_device *net) |