diff options
author | Jiri Pirko <jpirko@redhat.com> | 2010-04-01 17:22:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-03 17:22:15 -0400 |
commit | 22bedad3ce112d5ca1eaf043d4990fa2ed698c87 (patch) | |
tree | b6fba5688d48b1396f01d13ee53610dea7749c15 /net | |
parent | a748ee2426817a95b1f03012d8f339c45c722ae1 (diff) |
net: convert multicast list to list_head
Converts the list and the core manipulating with it to be the same as uc_list.
+uses two functions for adding/removing mc address (normal and "global"
variant) instead of a function parameter.
+removes dev_mcast.c completely.
+exposes netdev_hw_addr_list_* macros along with __hw_addr_* functions for
manipulation with lists on a sandbox (used in bonding and 80211 drivers)
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/802/garp.c | 4 | ||||
-rw-r--r-- | net/appletalk/ddp.c | 2 | ||||
-rw-r--r-- | net/bluetooth/bnep/netdev.c | 8 | ||||
-rw-r--r-- | net/core/Makefile | 5 | ||||
-rw-r--r-- | net/core/dev.c | 145 | ||||
-rw-r--r-- | net/core/dev_addr_lists.c | 305 | ||||
-rw-r--r-- | net/core/dev_mcast.c | 232 | ||||
-rw-r--r-- | net/decnet/dn_dev.c | 12 | ||||
-rw-r--r-- | net/ipv4/igmp.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_CLUSTERIP.c | 4 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 4 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 8 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/iface.c | 6 | ||||
-rw-r--r-- | net/mac80211/main.c | 2 | ||||
-rw-r--r-- | net/packet/af_packet.c | 4 |
16 files changed, 319 insertions, 429 deletions
diff --git a/net/802/garp.c b/net/802/garp.c index 1dcb0660c49d..78cff9ec2cb4 100644 --- a/net/802/garp.c +++ b/net/802/garp.c | |||
@@ -575,7 +575,7 @@ int garp_init_applicant(struct net_device *dev, struct garp_application *appl) | |||
575 | if (!app) | 575 | if (!app) |
576 | goto err2; | 576 | goto err2; |
577 | 577 | ||
578 | err = dev_mc_add(dev, appl->proto.group_address, ETH_ALEN, 0); | 578 | err = dev_mc_add(dev, appl->proto.group_address); |
579 | if (err < 0) | 579 | if (err < 0) |
580 | goto err3; | 580 | goto err3; |
581 | 581 | ||
@@ -615,7 +615,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl | |||
615 | garp_pdu_queue(app); | 615 | garp_pdu_queue(app); |
616 | garp_queue_xmit(app); | 616 | garp_queue_xmit(app); |
617 | 617 | ||
618 | dev_mc_delete(dev, appl->proto.group_address, ETH_ALEN, 0); | 618 | dev_mc_del(dev, appl->proto.group_address); |
619 | kfree(app); | 619 | kfree(app); |
620 | garp_release_port(dev); | 620 | garp_release_port(dev); |
621 | } | 621 | } |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 9fc4da56fb1d..1d15a60b23af 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -781,7 +781,7 @@ static int atif_ioctl(int cmd, void __user *arg) | |||
781 | atrtr_create(&rtdef, dev); | 781 | atrtr_create(&rtdef, dev); |
782 | } | 782 | } |
783 | } | 783 | } |
784 | dev_mc_add(dev, aarp_mcast, 6, 1); | 784 | dev_mc_add_global(dev, aarp_mcast); |
785 | return 0; | 785 | return 0; |
786 | 786 | ||
787 | case SIOCGIFADDR: | 787 | case SIOCGIFADDR: |
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 326ab453edb7..260a9507e542 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c | |||
@@ -87,7 +87,7 @@ static void bnep_net_set_mc_list(struct net_device *dev) | |||
87 | memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN); | 87 | memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN); |
88 | r->len = htons(ETH_ALEN * 2); | 88 | r->len = htons(ETH_ALEN * 2); |
89 | } else { | 89 | } else { |
90 | struct dev_mc_list *dmi; | 90 | struct netdev_hw_addr *ha; |
91 | int i, len = skb->len; | 91 | int i, len = skb->len; |
92 | 92 | ||
93 | if (dev->flags & IFF_BROADCAST) { | 93 | if (dev->flags & IFF_BROADCAST) { |
@@ -98,11 +98,11 @@ static void bnep_net_set_mc_list(struct net_device *dev) | |||
98 | /* FIXME: We should group addresses here. */ | 98 | /* FIXME: We should group addresses here. */ |
99 | 99 | ||
100 | i = 0; | 100 | i = 0; |
101 | netdev_for_each_mc_addr(dmi, dev) { | 101 | netdev_for_each_mc_addr(ha, dev) { |
102 | if (i == BNEP_MAX_MULTICAST_FILTERS) | 102 | if (i == BNEP_MAX_MULTICAST_FILTERS) |
103 | break; | 103 | break; |
104 | memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN); | 104 | memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); |
105 | memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN); | 105 | memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); |
106 | } | 106 | } |
107 | r->len = htons(skb->len - len); | 107 | r->len = htons(skb->len - len); |
108 | } | 108 | } |
diff --git a/net/core/Makefile b/net/core/Makefile index 0a899f1aadb9..51c3eec850ef 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -7,9 +7,8 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | |||
7 | 7 | ||
8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
9 | 9 | ||
10 | obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ | 10 | obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ |
11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ | 11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o |
12 | dev_addr_lists.o | ||
13 | 12 | ||
14 | obj-$(CONFIG_XFRM) += flow.o | 13 | obj-$(CONFIG_XFRM) += flow.o |
15 | obj-y += net-sysfs.o | 14 | obj-y += net-sysfs.o |
diff --git a/net/core/dev.c b/net/core/dev.c index 949c62dba719..2a9b7dd0bb6e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3968,140 +3968,6 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3968 | netif_addr_unlock_bh(dev); | 3968 | netif_addr_unlock_bh(dev); |
3969 | } | 3969 | } |
3970 | 3970 | ||
3971 | /* multicast addresses handling functions */ | ||
3972 | |||
3973 | int __dev_addr_delete(struct dev_addr_list **list, int *count, | ||
3974 | void *addr, int alen, int glbl) | ||
3975 | { | ||
3976 | struct dev_addr_list *da; | ||
3977 | |||
3978 | for (; (da = *list) != NULL; list = &da->next) { | ||
3979 | if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && | ||
3980 | alen == da->da_addrlen) { | ||
3981 | if (glbl) { | ||
3982 | int old_glbl = da->da_gusers; | ||
3983 | da->da_gusers = 0; | ||
3984 | if (old_glbl == 0) | ||
3985 | break; | ||
3986 | } | ||
3987 | if (--da->da_users) | ||
3988 | return 0; | ||
3989 | |||
3990 | *list = da->next; | ||
3991 | kfree(da); | ||
3992 | (*count)--; | ||
3993 | return 0; | ||
3994 | } | ||
3995 | } | ||
3996 | return -ENOENT; | ||
3997 | } | ||
3998 | |||
3999 | int __dev_addr_add(struct dev_addr_list **list, int *count, | ||
4000 | void *addr, int alen, int glbl) | ||
4001 | { | ||
4002 | struct dev_addr_list *da; | ||
4003 | |||
4004 | for (da = *list; da != NULL; da = da->next) { | ||
4005 | if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && | ||
4006 | da->da_addrlen == alen) { | ||
4007 | if (glbl) { | ||
4008 | int old_glbl = da->da_gusers; | ||
4009 | da->da_gusers = 1; | ||
4010 | if (old_glbl) | ||
4011 | return 0; | ||
4012 | } | ||
4013 | da->da_users++; | ||
4014 | return 0; | ||
4015 | } | ||
4016 | } | ||
4017 | |||
4018 | da = kzalloc(sizeof(*da), GFP_ATOMIC); | ||
4019 | if (da == NULL) | ||
4020 | return -ENOMEM; | ||
4021 | memcpy(da->da_addr, addr, alen); | ||
4022 | da->da_addrlen = alen; | ||
4023 | da->da_users = 1; | ||
4024 | da->da_gusers = glbl ? 1 : 0; | ||
4025 | da->next = *list; | ||
4026 | *list = da; | ||
4027 | (*count)++; | ||
4028 | return 0; | ||
4029 | } | ||
4030 | |||
4031 | |||
4032 | int __dev_addr_sync(struct dev_addr_list **to, int *to_count, | ||
4033 | struct dev_addr_list **from, int *from_count) | ||
4034 | { | ||
4035 | struct dev_addr_list *da, *next; | ||
4036 | int err = 0; | ||
4037 | |||
4038 | da = *from; | ||
4039 | while (da != NULL) { | ||
4040 | next = da->next; | ||
4041 | if (!da->da_synced) { | ||
4042 | err = __dev_addr_add(to, to_count, | ||
4043 | da->da_addr, da->da_addrlen, 0); | ||
4044 | if (err < 0) | ||
4045 | break; | ||
4046 | da->da_synced = 1; | ||
4047 | da->da_users++; | ||
4048 | } else if (da->da_users == 1) { | ||
4049 | __dev_addr_delete(to, to_count, | ||
4050 | da->da_addr, da->da_addrlen, 0); | ||
4051 | __dev_addr_delete(from, from_count, | ||
4052 | da->da_addr, da->da_addrlen, 0); | ||
4053 | } | ||
4054 | da = next; | ||
4055 | } | ||
4056 | return err; | ||
4057 | } | ||
4058 | EXPORT_SYMBOL_GPL(__dev_addr_sync); | ||
4059 | |||
4060 | void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, | ||
4061 | struct dev_addr_list **from, int *from_count) | ||
4062 | { | ||
4063 | struct dev_addr_list *da, *next; | ||
4064 | |||
4065 | da = *from; | ||
4066 | while (da != NULL) { | ||
4067 | next = da->next; | ||
4068 | if (da->da_synced) { | ||
4069 | __dev_addr_delete(to, to_count, | ||
4070 | da->da_addr, da->da_addrlen, 0); | ||
4071 | da->da_synced = 0; | ||
4072 | __dev_addr_delete(from, from_count, | ||
4073 | da->da_addr, da->da_addrlen, 0); | ||
4074 | } | ||
4075 | da = next; | ||
4076 | } | ||
4077 | } | ||
4078 | EXPORT_SYMBOL_GPL(__dev_addr_unsync); | ||
4079 | |||
4080 | static void __dev_addr_discard(struct dev_addr_list **list) | ||
4081 | { | ||
4082 | struct dev_addr_list *tmp; | ||
4083 | |||
4084 | while (*list != NULL) { | ||
4085 | tmp = *list; | ||
4086 | *list = tmp->next; | ||
4087 | if (tmp->da_users > tmp->da_gusers) | ||
4088 | printk("__dev_addr_discard: address leakage! " | ||
4089 | "da_users=%d\n", tmp->da_users); | ||
4090 | kfree(tmp); | ||
4091 | } | ||
4092 | } | ||
4093 | |||
4094 | void dev_addr_discard(struct net_device *dev) | ||
4095 | { | ||
4096 | netif_addr_lock_bh(dev); | ||
4097 | |||
4098 | __dev_addr_discard(&dev->mc_list); | ||
4099 | netdev_mc_count(dev) = 0; | ||
4100 | |||
4101 | netif_addr_unlock_bh(dev); | ||
4102 | } | ||
4103 | EXPORT_SYMBOL(dev_addr_discard); | ||
4104 | |||
4105 | /** | 3971 | /** |
4106 | * dev_get_flags - get flags reported to userspace | 3972 | * dev_get_flags - get flags reported to userspace |
4107 | * @dev: device | 3973 | * @dev: device |
@@ -4412,8 +4278,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
4412 | return -EINVAL; | 4278 | return -EINVAL; |
4413 | if (!netif_device_present(dev)) | 4279 | if (!netif_device_present(dev)) |
4414 | return -ENODEV; | 4280 | return -ENODEV; |
4415 | return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data, | 4281 | return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data); |
4416 | dev->addr_len, 1); | ||
4417 | 4282 | ||
4418 | case SIOCDELMULTI: | 4283 | case SIOCDELMULTI: |
4419 | if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) || | 4284 | if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) || |
@@ -4421,8 +4286,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
4421 | return -EINVAL; | 4286 | return -EINVAL; |
4422 | if (!netif_device_present(dev)) | 4287 | if (!netif_device_present(dev)) |
4423 | return -ENODEV; | 4288 | return -ENODEV; |
4424 | return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data, | 4289 | return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data); |
4425 | dev->addr_len, 1); | ||
4426 | 4290 | ||
4427 | case SIOCSIFTXQLEN: | 4291 | case SIOCSIFTXQLEN: |
4428 | if (ifr->ifr_qlen < 0) | 4292 | if (ifr->ifr_qlen < 0) |
@@ -4730,7 +4594,7 @@ static void rollback_registered_many(struct list_head *head) | |||
4730 | * Flush the unicast and multicast chains | 4594 | * Flush the unicast and multicast chains |
4731 | */ | 4595 | */ |
4732 | dev_uc_flush(dev); | 4596 | dev_uc_flush(dev); |
4733 | dev_addr_discard(dev); | 4597 | dev_mc_flush(dev); |
4734 | 4598 | ||
4735 | if (dev->netdev_ops->ndo_uninit) | 4599 | if (dev->netdev_ops->ndo_uninit) |
4736 | dev->netdev_ops->ndo_uninit(dev); | 4600 | dev->netdev_ops->ndo_uninit(dev); |
@@ -5310,6 +5174,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5310 | if (dev_addr_init(dev)) | 5174 | if (dev_addr_init(dev)) |
5311 | goto free_rx; | 5175 | goto free_rx; |
5312 | 5176 | ||
5177 | dev_mc_init(dev); | ||
5313 | dev_uc_init(dev); | 5178 | dev_uc_init(dev); |
5314 | 5179 | ||
5315 | dev_net_set(dev, &init_net); | 5180 | dev_net_set(dev, &init_net); |
@@ -5545,7 +5410,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
5545 | * Flush the unicast and multicast chains | 5410 | * Flush the unicast and multicast chains |
5546 | */ | 5411 | */ |
5547 | dev_uc_flush(dev); | 5412 | dev_uc_flush(dev); |
5548 | dev_addr_discard(dev); | 5413 | dev_mc_flush(dev); |
5549 | 5414 | ||
5550 | netdev_unregister_kobject(dev); | 5415 | netdev_unregister_kobject(dev); |
5551 | 5416 | ||
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 7e52b6d18add..37d5975e18a3 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c | |||
@@ -19,8 +19,9 @@ | |||
19 | * General list handling functions | 19 | * General list handling functions |
20 | */ | 20 | */ |
21 | 21 | ||
22 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, | 22 | static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, |
23 | int addr_len, unsigned char addr_type) | 23 | unsigned char *addr, int addr_len, |
24 | unsigned char addr_type, bool global) | ||
24 | { | 25 | { |
25 | struct netdev_hw_addr *ha; | 26 | struct netdev_hw_addr *ha; |
26 | int alloc_size; | 27 | int alloc_size; |
@@ -31,6 +32,13 @@ static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, | |||
31 | list_for_each_entry(ha, &list->list, list) { | 32 | list_for_each_entry(ha, &list->list, list) { |
32 | if (!memcmp(ha->addr, addr, addr_len) && | 33 | if (!memcmp(ha->addr, addr, addr_len) && |
33 | ha->type == addr_type) { | 34 | ha->type == addr_type) { |
35 | if (global) { | ||
36 | /* check if addr is already used as global */ | ||
37 | if (ha->global_use) | ||
38 | return 0; | ||
39 | else | ||
40 | ha->global_use = true; | ||
41 | } | ||
34 | ha->refcount++; | 42 | ha->refcount++; |
35 | return 0; | 43 | return 0; |
36 | } | 44 | } |
@@ -46,12 +54,19 @@ static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, | |||
46 | memcpy(ha->addr, addr, addr_len); | 54 | memcpy(ha->addr, addr, addr_len); |
47 | ha->type = addr_type; | 55 | ha->type = addr_type; |
48 | ha->refcount = 1; | 56 | ha->refcount = 1; |
57 | ha->global_use = global; | ||
49 | ha->synced = false; | 58 | ha->synced = false; |
50 | list_add_tail_rcu(&ha->list, &list->list); | 59 | list_add_tail_rcu(&ha->list, &list->list); |
51 | list->count++; | 60 | list->count++; |
52 | return 0; | 61 | return 0; |
53 | } | 62 | } |
54 | 63 | ||
64 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, | ||
65 | int addr_len, unsigned char addr_type) | ||
66 | { | ||
67 | return __hw_addr_add_ex(list, addr, addr_len, addr_type, false); | ||
68 | } | ||
69 | |||
55 | static void ha_rcu_free(struct rcu_head *head) | 70 | static void ha_rcu_free(struct rcu_head *head) |
56 | { | 71 | { |
57 | struct netdev_hw_addr *ha; | 72 | struct netdev_hw_addr *ha; |
@@ -60,14 +75,21 @@ static void ha_rcu_free(struct rcu_head *head) | |||
60 | kfree(ha); | 75 | kfree(ha); |
61 | } | 76 | } |
62 | 77 | ||
63 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, | 78 | static int __hw_addr_del_ex(struct netdev_hw_addr_list *list, |
64 | int addr_len, unsigned char addr_type) | 79 | unsigned char *addr, int addr_len, |
80 | unsigned char addr_type, bool global) | ||
65 | { | 81 | { |
66 | struct netdev_hw_addr *ha; | 82 | struct netdev_hw_addr *ha; |
67 | 83 | ||
68 | list_for_each_entry(ha, &list->list, list) { | 84 | list_for_each_entry(ha, &list->list, list) { |
69 | if (!memcmp(ha->addr, addr, addr_len) && | 85 | if (!memcmp(ha->addr, addr, addr_len) && |
70 | (ha->type == addr_type || !addr_type)) { | 86 | (ha->type == addr_type || !addr_type)) { |
87 | if (global) { | ||
88 | if (!ha->global_use) | ||
89 | break; | ||
90 | else | ||
91 | ha->global_use = false; | ||
92 | } | ||
71 | if (--ha->refcount) | 93 | if (--ha->refcount) |
72 | return 0; | 94 | return 0; |
73 | list_del_rcu(&ha->list); | 95 | list_del_rcu(&ha->list); |
@@ -79,10 +101,15 @@ static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, | |||
79 | return -ENOENT; | 101 | return -ENOENT; |
80 | } | 102 | } |
81 | 103 | ||
82 | static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, | 104 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, |
83 | struct netdev_hw_addr_list *from_list, | 105 | int addr_len, unsigned char addr_type) |
84 | int addr_len, | 106 | { |
85 | unsigned char addr_type) | 107 | return __hw_addr_del_ex(list, addr, addr_len, addr_type, false); |
108 | } | ||
109 | |||
110 | int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, | ||
111 | struct netdev_hw_addr_list *from_list, | ||
112 | int addr_len, unsigned char addr_type) | ||
86 | { | 113 | { |
87 | int err; | 114 | int err; |
88 | struct netdev_hw_addr *ha, *ha2; | 115 | struct netdev_hw_addr *ha, *ha2; |
@@ -105,11 +132,11 @@ unroll: | |||
105 | } | 132 | } |
106 | return err; | 133 | return err; |
107 | } | 134 | } |
135 | EXPORT_SYMBOL(__hw_addr_add_multiple); | ||
108 | 136 | ||
109 | static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, | 137 | void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, |
110 | struct netdev_hw_addr_list *from_list, | 138 | struct netdev_hw_addr_list *from_list, |
111 | int addr_len, | 139 | int addr_len, unsigned char addr_type) |
112 | unsigned char addr_type) | ||
113 | { | 140 | { |
114 | struct netdev_hw_addr *ha; | 141 | struct netdev_hw_addr *ha; |
115 | unsigned char type; | 142 | unsigned char type; |
@@ -119,10 +146,11 @@ static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, | |||
119 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); | 146 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); |
120 | } | 147 | } |
121 | } | 148 | } |
149 | EXPORT_SYMBOL(__hw_addr_del_multiple); | ||
122 | 150 | ||
123 | static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, | 151 | int __hw_addr_sync(struct netdev_hw_addr_list *to_list, |
124 | struct netdev_hw_addr_list *from_list, | 152 | struct netdev_hw_addr_list *from_list, |
125 | int addr_len) | 153 | int addr_len) |
126 | { | 154 | { |
127 | int err = 0; | 155 | int err = 0; |
128 | struct netdev_hw_addr *ha, *tmp; | 156 | struct netdev_hw_addr *ha, *tmp; |
@@ -142,10 +170,11 @@ static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, | |||
142 | } | 170 | } |
143 | return err; | 171 | return err; |
144 | } | 172 | } |
173 | EXPORT_SYMBOL(__hw_addr_sync); | ||
145 | 174 | ||
146 | static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, | 175 | void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, |
147 | struct netdev_hw_addr_list *from_list, | 176 | struct netdev_hw_addr_list *from_list, |
148 | int addr_len) | 177 | int addr_len) |
149 | { | 178 | { |
150 | struct netdev_hw_addr *ha, *tmp; | 179 | struct netdev_hw_addr *ha, *tmp; |
151 | 180 | ||
@@ -159,8 +188,9 @@ static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, | |||
159 | } | 188 | } |
160 | } | 189 | } |
161 | } | 190 | } |
191 | EXPORT_SYMBOL(__hw_addr_unsync); | ||
162 | 192 | ||
163 | static void __hw_addr_flush(struct netdev_hw_addr_list *list) | 193 | void __hw_addr_flush(struct netdev_hw_addr_list *list) |
164 | { | 194 | { |
165 | struct netdev_hw_addr *ha, *tmp; | 195 | struct netdev_hw_addr *ha, *tmp; |
166 | 196 | ||
@@ -170,12 +200,14 @@ static void __hw_addr_flush(struct netdev_hw_addr_list *list) | |||
170 | } | 200 | } |
171 | list->count = 0; | 201 | list->count = 0; |
172 | } | 202 | } |
203 | EXPORT_SYMBOL(__hw_addr_flush); | ||
173 | 204 | ||
174 | static void __hw_addr_init(struct netdev_hw_addr_list *list) | 205 | void __hw_addr_init(struct netdev_hw_addr_list *list) |
175 | { | 206 | { |
176 | INIT_LIST_HEAD(&list->list); | 207 | INIT_LIST_HEAD(&list->list); |
177 | list->count = 0; | 208 | list->count = 0; |
178 | } | 209 | } |
210 | EXPORT_SYMBOL(__hw_addr_init); | ||
179 | 211 | ||
180 | /* | 212 | /* |
181 | * Device addresses handling functions | 213 | * Device addresses handling functions |
@@ -475,4 +507,235 @@ EXPORT_SYMBOL(dev_uc_init); | |||
475 | * Multicast list handling functions | 507 | * Multicast list handling functions |
476 | */ | 508 | */ |
477 | 509 | ||
478 | /* To be filled here */ | 510 | static int __dev_mc_add(struct net_device *dev, unsigned char *addr, |
511 | bool global) | ||
512 | { | ||
513 | int err; | ||
514 | |||
515 | netif_addr_lock_bh(dev); | ||
516 | err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len, | ||
517 | NETDEV_HW_ADDR_T_MULTICAST, global); | ||
518 | if (!err) | ||
519 | __dev_set_rx_mode(dev); | ||
520 | netif_addr_unlock_bh(dev); | ||
521 | return err; | ||
522 | } | ||
523 | /** | ||
524 | * dev_mc_add - Add a multicast address | ||
525 | * @dev: device | ||
526 | * @addr: address to add | ||
527 | * | ||
528 | * Add a multicast address to the device or increase | ||
529 | * the reference count if it already exists. | ||
530 | */ | ||
531 | int dev_mc_add(struct net_device *dev, unsigned char *addr) | ||
532 | { | ||
533 | return __dev_mc_add(dev, addr, false); | ||
534 | } | ||
535 | EXPORT_SYMBOL(dev_mc_add); | ||
536 | |||
537 | /** | ||
538 | * dev_mc_add_global - Add a global multicast address | ||
539 | * @dev: device | ||
540 | * @addr: address to add | ||
541 | * | ||
542 | * Add a global multicast address to the device. | ||
543 | */ | ||
544 | int dev_mc_add_global(struct net_device *dev, unsigned char *addr) | ||
545 | { | ||
546 | return __dev_mc_add(dev, addr, true); | ||
547 | } | ||
548 | EXPORT_SYMBOL(dev_mc_add_global); | ||
549 | |||
550 | static int __dev_mc_del(struct net_device *dev, unsigned char *addr, | ||
551 | bool global) | ||
552 | { | ||
553 | int err; | ||
554 | |||
555 | netif_addr_lock_bh(dev); | ||
556 | err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len, | ||
557 | NETDEV_HW_ADDR_T_MULTICAST, global); | ||
558 | if (!err) | ||
559 | __dev_set_rx_mode(dev); | ||
560 | netif_addr_unlock_bh(dev); | ||
561 | return err; | ||
562 | } | ||
563 | |||
564 | /** | ||
565 | * dev_mc_del - Delete a multicast address. | ||
566 | * @dev: device | ||
567 | * @addr: address to delete | ||
568 | * | ||
569 | * Release reference to a multicast address and remove it | ||
570 | * from the device if the reference count drops to zero. | ||
571 | */ | ||
572 | int dev_mc_del(struct net_device *dev, unsigned char *addr) | ||
573 | { | ||
574 | return __dev_mc_del(dev, addr, false); | ||
575 | } | ||
576 | EXPORT_SYMBOL(dev_mc_del); | ||
577 | |||
578 | /** | ||
579 | * dev_mc_del_global - Delete a global multicast address. | ||
580 | * @dev: device | ||
581 | * @addr: address to delete | ||
582 | * | ||
583 | * Release reference to a multicast address and remove it | ||
584 | * from the device if the reference count drops to zero. | ||
585 | */ | ||
586 | int dev_mc_del_global(struct net_device *dev, unsigned char *addr) | ||
587 | { | ||
588 | return __dev_mc_del(dev, addr, true); | ||
589 | } | ||
590 | EXPORT_SYMBOL(dev_mc_del_global); | ||
591 | |||
592 | /** | ||
593 | * dev_mc_sync - Synchronize device's unicast list to another device | ||
594 | * @to: destination device | ||
595 | * @from: source device | ||
596 | * | ||
597 | * Add newly added addresses to the destination device and release | ||
598 | * addresses that have no users left. The source device must be | ||
599 | * locked by netif_tx_lock_bh. | ||
600 | * | ||
601 | * This function is intended to be called from the dev->set_multicast_list | ||
602 | * or dev->set_rx_mode function of layered software devices. | ||
603 | */ | ||
604 | int dev_mc_sync(struct net_device *to, struct net_device *from) | ||
605 | { | ||
606 | int err = 0; | ||
607 | |||
608 | if (to->addr_len != from->addr_len) | ||
609 | return -EINVAL; | ||
610 | |||
611 | netif_addr_lock_bh(to); | ||
612 | err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); | ||
613 | if (!err) | ||
614 | __dev_set_rx_mode(to); | ||
615 | netif_addr_unlock_bh(to); | ||
616 | return err; | ||
617 | } | ||
618 | EXPORT_SYMBOL(dev_mc_sync); | ||
619 | |||
620 | /** | ||
621 | * dev_mc_unsync - Remove synchronized addresses from the destination device | ||
622 | * @to: destination device | ||
623 | * @from: source device | ||
624 | * | ||
625 | * Remove all addresses that were added to the destination device by | ||
626 | * dev_mc_sync(). This function is intended to be called from the | ||
627 | * dev->stop function of layered software devices. | ||
628 | */ | ||
629 | void dev_mc_unsync(struct net_device *to, struct net_device *from) | ||
630 | { | ||
631 | if (to->addr_len != from->addr_len) | ||
632 | return; | ||
633 | |||
634 | netif_addr_lock_bh(from); | ||
635 | netif_addr_lock(to); | ||
636 | __hw_addr_unsync(&to->mc, &from->mc, to->addr_len); | ||
637 | __dev_set_rx_mode(to); | ||
638 | netif_addr_unlock(to); | ||
639 | netif_addr_unlock_bh(from); | ||
640 | } | ||
641 | EXPORT_SYMBOL(dev_mc_unsync); | ||
642 | |||
643 | /** | ||
644 | * dev_mc_flush - Flush multicast addresses | ||
645 | * @dev: device | ||
646 | * | ||
647 | * Flush multicast addresses. | ||
648 | */ | ||
649 | void dev_mc_flush(struct net_device *dev) | ||
650 | { | ||
651 | netif_addr_lock_bh(dev); | ||
652 | __hw_addr_flush(&dev->mc); | ||
653 | netif_addr_unlock_bh(dev); | ||
654 | } | ||
655 | EXPORT_SYMBOL(dev_mc_flush); | ||
656 | |||
657 | /** | ||
658 | * dev_mc_flush - Init multicast address list | ||
659 | * @dev: device | ||
660 | * | ||
661 | * Init multicast address list. | ||
662 | */ | ||
663 | void dev_mc_init(struct net_device *dev) | ||
664 | { | ||
665 | __hw_addr_init(&dev->mc); | ||
666 | } | ||
667 | EXPORT_SYMBOL(dev_mc_init); | ||
668 | |||
669 | #ifdef CONFIG_PROC_FS | ||
670 | #include <linux/proc_fs.h> | ||
671 | #include <linux/seq_file.h> | ||
672 | |||
673 | static int dev_mc_seq_show(struct seq_file *seq, void *v) | ||
674 | { | ||
675 | struct netdev_hw_addr *ha; | ||
676 | struct net_device *dev = v; | ||
677 | |||
678 | if (v == SEQ_START_TOKEN) | ||
679 | return 0; | ||
680 | |||
681 | netif_addr_lock_bh(dev); | ||
682 | netdev_for_each_mc_addr(ha, dev) { | ||
683 | int i; | ||
684 | |||
685 | seq_printf(seq, "%-4d %-15s %-5d %-5d ", dev->ifindex, | ||
686 | dev->name, ha->refcount, ha->global_use); | ||
687 | |||
688 | for (i = 0; i < dev->addr_len; i++) | ||
689 | seq_printf(seq, "%02x", ha->addr[i]); | ||
690 | |||
691 | seq_putc(seq, '\n'); | ||
692 | } | ||
693 | netif_addr_unlock_bh(dev); | ||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static const struct seq_operations dev_mc_seq_ops = { | ||
698 | .start = dev_seq_start, | ||
699 | .next = dev_seq_next, | ||
700 | .stop = dev_seq_stop, | ||
701 | .show = dev_mc_seq_show, | ||
702 | }; | ||
703 | |||
704 | static int dev_mc_seq_open(struct inode *inode, struct file *file) | ||
705 | { | ||
706 | return seq_open_net(inode, file, &dev_mc_seq_ops, | ||
707 | sizeof(struct seq_net_private)); | ||
708 | } | ||
709 | |||
710 | static const struct file_operations dev_mc_seq_fops = { | ||
711 | .owner = THIS_MODULE, | ||
712 | .open = dev_mc_seq_open, | ||
713 | .read = seq_read, | ||
714 | .llseek = seq_lseek, | ||
715 | .release = seq_release_net, | ||
716 | }; | ||
717 | |||
718 | #endif | ||
719 | |||
720 | static int __net_init dev_mc_net_init(struct net *net) | ||
721 | { | ||
722 | if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops)) | ||
723 | return -ENOMEM; | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static void __net_exit dev_mc_net_exit(struct net *net) | ||
728 | { | ||
729 | proc_net_remove(net, "dev_mcast"); | ||
730 | } | ||
731 | |||
732 | static struct pernet_operations __net_initdata dev_mc_net_ops = { | ||
733 | .init = dev_mc_net_init, | ||
734 | .exit = dev_mc_net_exit, | ||
735 | }; | ||
736 | |||
737 | void __init dev_mcast_init(void) | ||
738 | { | ||
739 | register_pernet_subsys(&dev_mc_net_ops); | ||
740 | } | ||
741 | |||
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c deleted file mode 100644 index 3dc295beb483..000000000000 --- a/net/core/dev_mcast.c +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | /* | ||
2 | * Linux NET3: Multicast List maintenance. | ||
3 | * | ||
4 | * Authors: | ||
5 | * Tim Kordas <tjk@nostromo.eeap.cwru.edu> | ||
6 | * Richard Underwood <richard@wuzz.demon.co.uk> | ||
7 | * | ||
8 | * Stir fried together from the IP multicast and CAP patches above | ||
9 | * Alan Cox <alan@lxorguk.ukuu.org.uk> | ||
10 | * | ||
11 | * Fixes: | ||
12 | * Alan Cox : Update the device on a real delete | ||
13 | * rather than any time but... | ||
14 | * Alan Cox : IFF_ALLMULTI support. | ||
15 | * Alan Cox : New format set_multicast_list() calls. | ||
16 | * Gleb Natapov : Remove dev_mc_lock. | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or | ||
19 | * modify it under the terms of the GNU General Public License | ||
20 | * as published by the Free Software Foundation; either version | ||
21 | * 2 of the License, or (at your option) any later version. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <asm/uaccess.h> | ||
26 | #include <asm/system.h> | ||
27 | #include <linux/bitops.h> | ||
28 | #include <linux/types.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/string.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/socket.h> | ||
33 | #include <linux/sockios.h> | ||
34 | #include <linux/in.h> | ||
35 | #include <linux/errno.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/if_ether.h> | ||
38 | #include <linux/inet.h> | ||
39 | #include <linux/netdevice.h> | ||
40 | #include <linux/etherdevice.h> | ||
41 | #include <linux/proc_fs.h> | ||
42 | #include <linux/seq_file.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <net/net_namespace.h> | ||
45 | #include <net/ip.h> | ||
46 | #include <net/route.h> | ||
47 | #include <linux/skbuff.h> | ||
48 | #include <net/sock.h> | ||
49 | #include <net/arp.h> | ||
50 | |||
51 | |||
52 | /* | ||
53 | * Device multicast list maintenance. | ||
54 | * | ||
55 | * This is used both by IP and by the user level maintenance functions. | ||
56 | * Unlike BSD we maintain a usage count on a given multicast address so | ||
57 | * that a casual user application can add/delete multicasts used by | ||
58 | * protocols without doing damage to the protocols when it deletes the | ||
59 | * entries. It also helps IP as it tracks overlapping maps. | ||
60 | * | ||
61 | * Device mc lists are changed by bh at least if IPv6 is enabled, | ||
62 | * so that it must be bh protected. | ||
63 | * | ||
64 | * We block accesses to device mc filters with netif_tx_lock. | ||
65 | */ | ||
66 | |||
67 | /* | ||
68 | * Delete a device level multicast | ||
69 | */ | ||
70 | |||
71 | int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) | ||
72 | { | ||
73 | int err; | ||
74 | |||
75 | netif_addr_lock_bh(dev); | ||
76 | err = __dev_addr_delete(&dev->mc_list, &dev->mc_count, | ||
77 | addr, alen, glbl); | ||
78 | if (!err) { | ||
79 | /* | ||
80 | * We have altered the list, so the card | ||
81 | * loaded filter is now wrong. Fix it | ||
82 | */ | ||
83 | |||
84 | __dev_set_rx_mode(dev); | ||
85 | } | ||
86 | netif_addr_unlock_bh(dev); | ||
87 | return err; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Add a device level multicast | ||
92 | */ | ||
93 | |||
94 | int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) | ||
95 | { | ||
96 | int err; | ||
97 | |||
98 | netif_addr_lock_bh(dev); | ||
99 | if (alen != dev->addr_len) | ||
100 | err = -EINVAL; | ||
101 | else | ||
102 | err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); | ||
103 | if (!err) | ||
104 | __dev_set_rx_mode(dev); | ||
105 | netif_addr_unlock_bh(dev); | ||
106 | return err; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * dev_mc_sync - Synchronize device's multicast list to another device | ||
111 | * @to: destination device | ||
112 | * @from: source device | ||
113 | * | ||
114 | * Add newly added addresses to the destination device and release | ||
115 | * addresses that have no users left. The source device must be | ||
116 | * locked by netif_tx_lock_bh. | ||
117 | * | ||
118 | * This function is intended to be called from the dev->set_multicast_list | ||
119 | * or dev->set_rx_mode function of layered software devices. | ||
120 | */ | ||
121 | int dev_mc_sync(struct net_device *to, struct net_device *from) | ||
122 | { | ||
123 | int err = 0; | ||
124 | |||
125 | netif_addr_lock_bh(to); | ||
126 | err = __dev_addr_sync(&to->mc_list, &to->mc_count, | ||
127 | &from->mc_list, &from->mc_count); | ||
128 | if (!err) | ||
129 | __dev_set_rx_mode(to); | ||
130 | netif_addr_unlock_bh(to); | ||
131 | |||
132 | return err; | ||
133 | } | ||
134 | EXPORT_SYMBOL(dev_mc_sync); | ||
135 | |||
136 | |||
137 | /** | ||
138 | * dev_mc_unsync - Remove synchronized addresses from the destination | ||
139 | * device | ||
140 | * @to: destination device | ||
141 | * @from: source device | ||
142 | * | ||
143 | * Remove all addresses that were added to the destination device by | ||
144 | * dev_mc_sync(). This function is intended to be called from the | ||
145 | * dev->stop function of layered software devices. | ||
146 | */ | ||
147 | void dev_mc_unsync(struct net_device *to, struct net_device *from) | ||
148 | { | ||
149 | netif_addr_lock_bh(from); | ||
150 | netif_addr_lock(to); | ||
151 | |||
152 | __dev_addr_unsync(&to->mc_list, &to->mc_count, | ||
153 | &from->mc_list, &from->mc_count); | ||
154 | __dev_set_rx_mode(to); | ||
155 | |||
156 | netif_addr_unlock(to); | ||
157 | netif_addr_unlock_bh(from); | ||
158 | } | ||
159 | EXPORT_SYMBOL(dev_mc_unsync); | ||
160 | |||
161 | #ifdef CONFIG_PROC_FS | ||
162 | static int dev_mc_seq_show(struct seq_file *seq, void *v) | ||
163 | { | ||
164 | struct dev_addr_list *m; | ||
165 | struct net_device *dev = v; | ||
166 | |||
167 | if (v == SEQ_START_TOKEN) | ||
168 | return 0; | ||
169 | |||
170 | netif_addr_lock_bh(dev); | ||
171 | for (m = dev->mc_list; m; m = m->next) { | ||
172 | int i; | ||
173 | |||
174 | seq_printf(seq, "%-4d %-15s %-5d %-5d ", dev->ifindex, | ||
175 | dev->name, m->dmi_users, m->dmi_gusers); | ||
176 | |||
177 | for (i = 0; i < m->dmi_addrlen; i++) | ||
178 | seq_printf(seq, "%02x", m->dmi_addr[i]); | ||
179 | |||
180 | seq_putc(seq, '\n'); | ||
181 | } | ||
182 | netif_addr_unlock_bh(dev); | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static const struct seq_operations dev_mc_seq_ops = { | ||
187 | .start = dev_seq_start, | ||
188 | .next = dev_seq_next, | ||
189 | .stop = dev_seq_stop, | ||
190 | .show = dev_mc_seq_show, | ||
191 | }; | ||
192 | |||
193 | static int dev_mc_seq_open(struct inode *inode, struct file *file) | ||
194 | { | ||
195 | return seq_open_net(inode, file, &dev_mc_seq_ops, | ||
196 | sizeof(struct seq_net_private)); | ||
197 | } | ||
198 | |||
199 | static const struct file_operations dev_mc_seq_fops = { | ||
200 | .owner = THIS_MODULE, | ||
201 | .open = dev_mc_seq_open, | ||
202 | .read = seq_read, | ||
203 | .llseek = seq_lseek, | ||
204 | .release = seq_release_net, | ||
205 | }; | ||
206 | |||
207 | #endif | ||
208 | |||
209 | static int __net_init dev_mc_net_init(struct net *net) | ||
210 | { | ||
211 | if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops)) | ||
212 | return -ENOMEM; | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static void __net_exit dev_mc_net_exit(struct net *net) | ||
217 | { | ||
218 | proc_net_remove(net, "dev_mcast"); | ||
219 | } | ||
220 | |||
221 | static struct pernet_operations __net_initdata dev_mc_net_ops = { | ||
222 | .init = dev_mc_net_init, | ||
223 | .exit = dev_mc_net_exit, | ||
224 | }; | ||
225 | |||
226 | void __init dev_mcast_init(void) | ||
227 | { | ||
228 | register_pernet_subsys(&dev_mc_net_ops); | ||
229 | } | ||
230 | |||
231 | EXPORT_SYMBOL(dev_mc_add); | ||
232 | EXPORT_SYMBOL(dev_mc_delete); | ||
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 238af093495b..f3e4734d207f 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -349,7 +349,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de | |||
349 | if (dn_db->dev->type == ARPHRD_ETHER) { | 349 | if (dn_db->dev->type == ARPHRD_ETHER) { |
350 | if (ifa1->ifa_local != dn_eth2dn(dev->dev_addr)) { | 350 | if (ifa1->ifa_local != dn_eth2dn(dev->dev_addr)) { |
351 | dn_dn2eth(mac_addr, ifa1->ifa_local); | 351 | dn_dn2eth(mac_addr, ifa1->ifa_local); |
352 | dev_mc_delete(dev, mac_addr, ETH_ALEN, 0); | 352 | dev_mc_del(dev, mac_addr); |
353 | } | 353 | } |
354 | } | 354 | } |
355 | 355 | ||
@@ -380,7 +380,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) | |||
380 | if (dev->type == ARPHRD_ETHER) { | 380 | if (dev->type == ARPHRD_ETHER) { |
381 | if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) { | 381 | if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) { |
382 | dn_dn2eth(mac_addr, ifa->ifa_local); | 382 | dn_dn2eth(mac_addr, ifa->ifa_local); |
383 | dev_mc_add(dev, mac_addr, ETH_ALEN, 0); | 383 | dev_mc_add(dev, mac_addr); |
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
@@ -1000,9 +1000,9 @@ static int dn_eth_up(struct net_device *dev) | |||
1000 | struct dn_dev *dn_db = dev->dn_ptr; | 1000 | struct dn_dev *dn_db = dev->dn_ptr; |
1001 | 1001 | ||
1002 | if (dn_db->parms.forwarding == 0) | 1002 | if (dn_db->parms.forwarding == 0) |
1003 | dev_mc_add(dev, dn_rt_all_end_mcast, ETH_ALEN, 0); | 1003 | dev_mc_add(dev, dn_rt_all_end_mcast); |
1004 | else | 1004 | else |
1005 | dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0); | 1005 | dev_mc_add(dev, dn_rt_all_rt_mcast); |
1006 | 1006 | ||
1007 | dn_db->use_long = 1; | 1007 | dn_db->use_long = 1; |
1008 | 1008 | ||
@@ -1014,9 +1014,9 @@ static void dn_eth_down(struct net_device *dev) | |||
1014 | struct dn_dev *dn_db = dev->dn_ptr; | 1014 | struct dn_dev *dn_db = dev->dn_ptr; |
1015 | 1015 | ||
1016 | if (dn_db->parms.forwarding == 0) | 1016 | if (dn_db->parms.forwarding == 0) |
1017 | dev_mc_delete(dev, dn_rt_all_end_mcast, ETH_ALEN, 0); | 1017 | dev_mc_del(dev, dn_rt_all_end_mcast); |
1018 | else | 1018 | else |
1019 | dev_mc_delete(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0); | 1019 | dev_mc_del(dev, dn_rt_all_rt_mcast); |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | static void dn_dev_set_timer(struct net_device *dev); | 1022 | static void dn_dev_set_timer(struct net_device *dev); |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 63bf298ca109..51824c42b775 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -997,7 +997,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr) | |||
997 | --ANK | 997 | --ANK |
998 | */ | 998 | */ |
999 | if (arp_mc_map(addr, buf, dev, 0) == 0) | 999 | if (arp_mc_map(addr, buf, dev, 0) == 0) |
1000 | dev_mc_add(dev, buf, dev->addr_len, 0); | 1000 | dev_mc_add(dev, buf); |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | /* | 1003 | /* |
@@ -1010,7 +1010,7 @@ static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr) | |||
1010 | struct net_device *dev = in_dev->dev; | 1010 | struct net_device *dev = in_dev->dev; |
1011 | 1011 | ||
1012 | if (arp_mc_map(addr, buf, dev, 0) == 0) | 1012 | if (arp_mc_map(addr, buf, dev, 0) == 0) |
1013 | dev_mc_delete(dev, buf, dev->addr_len, 0); | 1013 | dev_mc_del(dev, buf); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | #ifdef CONFIG_IP_MULTICAST | 1016 | #ifdef CONFIG_IP_MULTICAST |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 0886f96c736b..a2208b7b313d 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -87,7 +87,7 @@ clusterip_config_entry_put(struct clusterip_config *c) | |||
87 | list_del(&c->list); | 87 | list_del(&c->list); |
88 | write_unlock_bh(&clusterip_lock); | 88 | write_unlock_bh(&clusterip_lock); |
89 | 89 | ||
90 | dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0); | 90 | dev_mc_del(c->dev, c->clustermac); |
91 | dev_put(c->dev); | 91 | dev_put(c->dev); |
92 | 92 | ||
93 | /* In case anyone still accesses the file, the open/close | 93 | /* In case anyone still accesses the file, the open/close |
@@ -396,7 +396,7 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par) | |||
396 | dev_put(dev); | 396 | dev_put(dev); |
397 | return false; | 397 | return false; |
398 | } | 398 | } |
399 | dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0); | 399 | dev_mc_add(config->dev, config->clustermac); |
400 | } | 400 | } |
401 | } | 401 | } |
402 | cipinfo->config = config; | 402 | cipinfo->config = config; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index bcd971915969..37d1868c0064 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -714,7 +714,7 @@ static void igmp6_group_added(struct ifmcaddr6 *mc) | |||
714 | if (!(mc->mca_flags&MAF_LOADED)) { | 714 | if (!(mc->mca_flags&MAF_LOADED)) { |
715 | mc->mca_flags |= MAF_LOADED; | 715 | mc->mca_flags |= MAF_LOADED; |
716 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) | 716 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) |
717 | dev_mc_add(dev, buf, dev->addr_len, 0); | 717 | dev_mc_add(dev, buf); |
718 | } | 718 | } |
719 | spin_unlock_bh(&mc->mca_lock); | 719 | spin_unlock_bh(&mc->mca_lock); |
720 | 720 | ||
@@ -740,7 +740,7 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc) | |||
740 | if (mc->mca_flags&MAF_LOADED) { | 740 | if (mc->mca_flags&MAF_LOADED) { |
741 | mc->mca_flags &= ~MAF_LOADED; | 741 | mc->mca_flags &= ~MAF_LOADED; |
742 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) | 742 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) |
743 | dev_mc_delete(dev, buf, dev->addr_len, 0); | 743 | dev_mc_del(dev, buf); |
744 | } | 744 | } |
745 | 745 | ||
746 | if (mc->mca_flags & MAF_NOREPORT) | 746 | if (mc->mca_flags & MAF_NOREPORT) |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index c3d844093a2f..9179196da264 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -84,16 +84,14 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
84 | } | 84 | } |
85 | 85 | ||
86 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, | 86 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, |
87 | int mc_count, | 87 | struct netdev_hw_addr_list *mc_list) |
88 | struct dev_addr_list *mc_list) | ||
89 | { | 88 | { |
90 | u64 ret = 0; | 89 | u64 ret = 0; |
91 | 90 | ||
92 | if (local->ops->prepare_multicast) | 91 | if (local->ops->prepare_multicast) |
93 | ret = local->ops->prepare_multicast(&local->hw, mc_count, | 92 | ret = local->ops->prepare_multicast(&local->hw, mc_list); |
94 | mc_list); | ||
95 | 93 | ||
96 | trace_drv_prepare_multicast(local, mc_count, ret); | 94 | trace_drv_prepare_multicast(local, mc_list->count, ret); |
97 | 95 | ||
98 | return ret; | 96 | return ret; |
99 | } | 97 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ab369e2a5282..7fdacf9408b1 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -646,8 +646,7 @@ struct ieee80211_local { | |||
646 | struct work_struct recalc_smps; | 646 | struct work_struct recalc_smps; |
647 | 647 | ||
648 | /* aggregated multicast list */ | 648 | /* aggregated multicast list */ |
649 | struct dev_addr_list *mc_list; | 649 | struct netdev_hw_addr_list mc_list; |
650 | int mc_count; | ||
651 | 650 | ||
652 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ | 651 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ |
653 | 652 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b4ec59a8dc03..00f3a93c6b04 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -412,8 +412,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
412 | 412 | ||
413 | netif_addr_lock_bh(dev); | 413 | netif_addr_lock_bh(dev); |
414 | spin_lock_bh(&local->filter_lock); | 414 | spin_lock_bh(&local->filter_lock); |
415 | __dev_addr_unsync(&local->mc_list, &local->mc_count, | 415 | __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len); |
416 | &dev->mc_list, &dev->mc_count); | ||
417 | spin_unlock_bh(&local->filter_lock); | 416 | spin_unlock_bh(&local->filter_lock); |
418 | netif_addr_unlock_bh(dev); | 417 | netif_addr_unlock_bh(dev); |
419 | 418 | ||
@@ -596,8 +595,7 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
596 | sdata->flags ^= IEEE80211_SDATA_PROMISC; | 595 | sdata->flags ^= IEEE80211_SDATA_PROMISC; |
597 | } | 596 | } |
598 | spin_lock_bh(&local->filter_lock); | 597 | spin_lock_bh(&local->filter_lock); |
599 | __dev_addr_sync(&local->mc_list, &local->mc_count, | 598 | __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); |
600 | &dev->mc_list, &dev->mc_count); | ||
601 | spin_unlock_bh(&local->filter_lock); | 599 | spin_unlock_bh(&local->filter_lock); |
602 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | 600 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); |
603 | } | 601 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 06c33b68d8e5..84ad249a4e2e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -71,7 +71,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
71 | spin_lock_bh(&local->filter_lock); | 71 | spin_lock_bh(&local->filter_lock); |
72 | changed_flags = local->filter_flags ^ new_flags; | 72 | changed_flags = local->filter_flags ^ new_flags; |
73 | 73 | ||
74 | mc = drv_prepare_multicast(local, local->mc_count, local->mc_list); | 74 | mc = drv_prepare_multicast(local, &local->mc_list); |
75 | spin_unlock_bh(&local->filter_lock); | 75 | spin_unlock_bh(&local->filter_lock); |
76 | 76 | ||
77 | /* be a bit nasty */ | 77 | /* be a bit nasty */ |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 48c1e0ae565f..b0f037cc899c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1691,9 +1691,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
1691 | if (i->alen != dev->addr_len) | 1691 | if (i->alen != dev->addr_len) |
1692 | return -EINVAL; | 1692 | return -EINVAL; |
1693 | if (what > 0) | 1693 | if (what > 0) |
1694 | return dev_mc_add(dev, i->addr, i->alen, 0); | 1694 | return dev_mc_add(dev, i->addr); |
1695 | else | 1695 | else |
1696 | return dev_mc_delete(dev, i->addr, i->alen, 0); | 1696 | return dev_mc_del(dev, i->addr); |
1697 | break; | 1697 | break; |
1698 | case PACKET_MR_PROMISC: | 1698 | case PACKET_MR_PROMISC: |
1699 | return dev_set_promiscuity(dev, what); | 1699 | return dev_set_promiscuity(dev, what); |