diff options
author | nikolay@redhat.com <nikolay@redhat.com> | 2013-03-11 22:49:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-15 08:22:20 -0400 |
commit | 8a7fbfab4be39b8690543f3d29b26860d2f6c576 (patch) | |
tree | 6618fe6878b31f43d094be20643df7e7186083f1 | |
parent | 1e32b0c65c9e3f1a09cb5d1bcc0c5becf849d85f (diff) |
netxen: write IP address to firmware when using bonding
This patch allows LRO aggregation on bonded devices that contain an
NX3031 device. It also adds a for_each_netdev_in_bond_rcu(bond, slave)
macro which executes for each slave that has bond as master.
V3: After testing and discussing this with Rajesh, I decided to keep the
vlan ip cache and just rename it to ip_cache since it will store bond
ip addresses too. A new master flag has been added to the ip cache to
denote that the address has been added because of a master device.
I've taken care of the enslave/release cases by checking for various
combinations of events and flags (e.g. netxen has a master, it's a
bond master and it's not marked as a slave means it is being enslaved
and is dev_open()ed in bond_enslave).
I've changed netxen_free_ip_list() to have a "master" parameter which
causes all IP addresses marked as master to be deleted (used when a
netxen is being released). I've made the patch use the new upper
device API as well. The following cases were tested:
- bond -> netxen
- vlan -> netxen
- vlan -> bond -> netxen
V2: Remove local ip caching, retrieve addresses dynamically and
restore them if necessary.
Note: Tested with NX3031 adapter.
Tested-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Andy Gospodarek <agospoda@redhat.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 220 | ||||
-rw-r--r-- | include/linux/netdevice.h | 8 |
3 files changed, 155 insertions, 78 deletions
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index eb3dfdbb642b..322a36b76727 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h | |||
@@ -955,9 +955,10 @@ typedef struct nx_mac_list_s { | |||
955 | uint8_t mac_addr[ETH_ALEN+2]; | 955 | uint8_t mac_addr[ETH_ALEN+2]; |
956 | } nx_mac_list_t; | 956 | } nx_mac_list_t; |
957 | 957 | ||
958 | struct nx_vlan_ip_list { | 958 | struct nx_ip_list { |
959 | struct list_head list; | 959 | struct list_head list; |
960 | __be32 ip_addr; | 960 | __be32 ip_addr; |
961 | bool master; | ||
961 | }; | 962 | }; |
962 | 963 | ||
963 | /* | 964 | /* |
@@ -1605,7 +1606,7 @@ struct netxen_adapter { | |||
1605 | struct net_device *netdev; | 1606 | struct net_device *netdev; |
1606 | struct pci_dev *pdev; | 1607 | struct pci_dev *pdev; |
1607 | struct list_head mac_list; | 1608 | struct list_head mac_list; |
1608 | struct list_head vlan_ip_list; | 1609 | struct list_head ip_list; |
1609 | 1610 | ||
1610 | spinlock_t tx_clean_lock; | 1611 | spinlock_t tx_clean_lock; |
1611 | 1612 | ||
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 501f49207da5..7867aebc05f2 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
@@ -90,7 +90,7 @@ static irqreturn_t netxen_intr(int irq, void *data); | |||
90 | static irqreturn_t netxen_msi_intr(int irq, void *data); | 90 | static irqreturn_t netxen_msi_intr(int irq, void *data); |
91 | static irqreturn_t netxen_msix_intr(int irq, void *data); | 91 | static irqreturn_t netxen_msix_intr(int irq, void *data); |
92 | 92 | ||
93 | static void netxen_free_vlan_ip_list(struct netxen_adapter *); | 93 | static void netxen_free_ip_list(struct netxen_adapter *, bool); |
94 | static void netxen_restore_indev_addr(struct net_device *dev, unsigned long); | 94 | static void netxen_restore_indev_addr(struct net_device *dev, unsigned long); |
95 | static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, | 95 | static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, |
96 | struct rtnl_link_stats64 *stats); | 96 | struct rtnl_link_stats64 *stats); |
@@ -1450,7 +1450,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1450 | 1450 | ||
1451 | spin_lock_init(&adapter->tx_clean_lock); | 1451 | spin_lock_init(&adapter->tx_clean_lock); |
1452 | INIT_LIST_HEAD(&adapter->mac_list); | 1452 | INIT_LIST_HEAD(&adapter->mac_list); |
1453 | INIT_LIST_HEAD(&adapter->vlan_ip_list); | 1453 | INIT_LIST_HEAD(&adapter->ip_list); |
1454 | 1454 | ||
1455 | err = netxen_setup_pci_map(adapter); | 1455 | err = netxen_setup_pci_map(adapter); |
1456 | if (err) | 1456 | if (err) |
@@ -1585,7 +1585,7 @@ static void netxen_nic_remove(struct pci_dev *pdev) | |||
1585 | 1585 | ||
1586 | cancel_work_sync(&adapter->tx_timeout_task); | 1586 | cancel_work_sync(&adapter->tx_timeout_task); |
1587 | 1587 | ||
1588 | netxen_free_vlan_ip_list(adapter); | 1588 | netxen_free_ip_list(adapter, false); |
1589 | netxen_nic_detach(adapter); | 1589 | netxen_nic_detach(adapter); |
1590 | 1590 | ||
1591 | nx_decr_dev_ref_cnt(adapter); | 1591 | nx_decr_dev_ref_cnt(adapter); |
@@ -3137,62 +3137,77 @@ netxen_destip_supported(struct netxen_adapter *adapter) | |||
3137 | } | 3137 | } |
3138 | 3138 | ||
3139 | static void | 3139 | static void |
3140 | netxen_free_vlan_ip_list(struct netxen_adapter *adapter) | 3140 | netxen_free_ip_list(struct netxen_adapter *adapter, bool master) |
3141 | { | 3141 | { |
3142 | struct nx_vlan_ip_list *cur; | 3142 | struct nx_ip_list *cur, *tmp_cur; |
3143 | struct list_head *head = &adapter->vlan_ip_list; | ||
3144 | 3143 | ||
3145 | while (!list_empty(head)) { | 3144 | list_for_each_entry_safe(cur, tmp_cur, &adapter->ip_list, list) { |
3146 | cur = list_entry(head->next, struct nx_vlan_ip_list, list); | 3145 | if (master) { |
3147 | netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN); | 3146 | if (cur->master) { |
3148 | list_del(&cur->list); | 3147 | netxen_config_ipaddr(adapter, cur->ip_addr, |
3149 | kfree(cur); | 3148 | NX_IP_DOWN); |
3149 | list_del(&cur->list); | ||
3150 | kfree(cur); | ||
3151 | } | ||
3152 | } else { | ||
3153 | netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN); | ||
3154 | list_del(&cur->list); | ||
3155 | kfree(cur); | ||
3156 | } | ||
3150 | } | 3157 | } |
3151 | |||
3152 | } | 3158 | } |
3153 | static void | 3159 | |
3154 | netxen_list_config_vlan_ip(struct netxen_adapter *adapter, | 3160 | static bool |
3161 | netxen_list_config_ip(struct netxen_adapter *adapter, | ||
3155 | struct in_ifaddr *ifa, unsigned long event) | 3162 | struct in_ifaddr *ifa, unsigned long event) |
3156 | { | 3163 | { |
3157 | struct net_device *dev; | 3164 | struct net_device *dev; |
3158 | struct nx_vlan_ip_list *cur, *tmp_cur; | 3165 | struct nx_ip_list *cur, *tmp_cur; |
3159 | struct list_head *head; | 3166 | struct list_head *head; |
3167 | bool ret = false; | ||
3160 | 3168 | ||
3161 | dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; | 3169 | dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; |
3162 | 3170 | ||
3163 | if (dev == NULL) | 3171 | if (dev == NULL) |
3164 | return; | 3172 | goto out; |
3165 | |||
3166 | if (!is_vlan_dev(dev)) | ||
3167 | return; | ||
3168 | 3173 | ||
3169 | switch (event) { | 3174 | switch (event) { |
3170 | case NX_IP_UP: | 3175 | case NX_IP_UP: |
3171 | list_for_each(head, &adapter->vlan_ip_list) { | 3176 | list_for_each(head, &adapter->ip_list) { |
3172 | cur = list_entry(head, struct nx_vlan_ip_list, list); | 3177 | cur = list_entry(head, struct nx_ip_list, list); |
3173 | 3178 | ||
3174 | if (cur->ip_addr == ifa->ifa_address) | 3179 | if (cur->ip_addr == ifa->ifa_address) |
3175 | return; | 3180 | goto out; |
3176 | } | 3181 | } |
3177 | 3182 | ||
3178 | cur = kzalloc(sizeof(struct nx_vlan_ip_list), GFP_ATOMIC); | 3183 | cur = kzalloc(sizeof(struct nx_ip_list), GFP_ATOMIC); |
3179 | if (cur == NULL) | 3184 | if (cur == NULL) |
3180 | return; | 3185 | goto out; |
3181 | 3186 | if (dev->priv_flags & IFF_802_1Q_VLAN) | |
3187 | dev = vlan_dev_real_dev(dev); | ||
3188 | cur->master = !!netif_is_bond_master(dev); | ||
3182 | cur->ip_addr = ifa->ifa_address; | 3189 | cur->ip_addr = ifa->ifa_address; |
3183 | list_add_tail(&cur->list, &adapter->vlan_ip_list); | 3190 | list_add_tail(&cur->list, &adapter->ip_list); |
3191 | netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP); | ||
3192 | ret = true; | ||
3184 | break; | 3193 | break; |
3185 | case NX_IP_DOWN: | 3194 | case NX_IP_DOWN: |
3186 | list_for_each_entry_safe(cur, tmp_cur, | 3195 | list_for_each_entry_safe(cur, tmp_cur, |
3187 | &adapter->vlan_ip_list, list) { | 3196 | &adapter->ip_list, list) { |
3188 | if (cur->ip_addr == ifa->ifa_address) { | 3197 | if (cur->ip_addr == ifa->ifa_address) { |
3189 | list_del(&cur->list); | 3198 | list_del(&cur->list); |
3190 | kfree(cur); | 3199 | kfree(cur); |
3200 | netxen_config_ipaddr(adapter, ifa->ifa_address, | ||
3201 | NX_IP_DOWN); | ||
3202 | ret = true; | ||
3191 | break; | 3203 | break; |
3192 | } | 3204 | } |
3193 | } | 3205 | } |
3194 | } | 3206 | } |
3207 | out: | ||
3208 | return ret; | ||
3195 | } | 3209 | } |
3210 | |||
3196 | static void | 3211 | static void |
3197 | netxen_config_indev_addr(struct netxen_adapter *adapter, | 3212 | netxen_config_indev_addr(struct netxen_adapter *adapter, |
3198 | struct net_device *dev, unsigned long event) | 3213 | struct net_device *dev, unsigned long event) |
@@ -3209,14 +3224,10 @@ netxen_config_indev_addr(struct netxen_adapter *adapter, | |||
3209 | for_ifa(indev) { | 3224 | for_ifa(indev) { |
3210 | switch (event) { | 3225 | switch (event) { |
3211 | case NETDEV_UP: | 3226 | case NETDEV_UP: |
3212 | netxen_config_ipaddr(adapter, | 3227 | netxen_list_config_ip(adapter, ifa, NX_IP_UP); |
3213 | ifa->ifa_address, NX_IP_UP); | ||
3214 | netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP); | ||
3215 | break; | 3228 | break; |
3216 | case NETDEV_DOWN: | 3229 | case NETDEV_DOWN: |
3217 | netxen_config_ipaddr(adapter, | 3230 | netxen_list_config_ip(adapter, ifa, NX_IP_DOWN); |
3218 | ifa->ifa_address, NX_IP_DOWN); | ||
3219 | netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN); | ||
3220 | break; | 3231 | break; |
3221 | default: | 3232 | default: |
3222 | break; | 3233 | break; |
@@ -3231,23 +3242,78 @@ netxen_restore_indev_addr(struct net_device *netdev, unsigned long event) | |||
3231 | 3242 | ||
3232 | { | 3243 | { |
3233 | struct netxen_adapter *adapter = netdev_priv(netdev); | 3244 | struct netxen_adapter *adapter = netdev_priv(netdev); |
3234 | struct nx_vlan_ip_list *pos, *tmp_pos; | 3245 | struct nx_ip_list *pos, *tmp_pos; |
3235 | unsigned long ip_event; | 3246 | unsigned long ip_event; |
3236 | 3247 | ||
3237 | ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN; | 3248 | ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN; |
3238 | netxen_config_indev_addr(adapter, netdev, event); | 3249 | netxen_config_indev_addr(adapter, netdev, event); |
3239 | 3250 | ||
3240 | list_for_each_entry_safe(pos, tmp_pos, &adapter->vlan_ip_list, list) { | 3251 | list_for_each_entry_safe(pos, tmp_pos, &adapter->ip_list, list) { |
3241 | netxen_config_ipaddr(adapter, pos->ip_addr, ip_event); | 3252 | netxen_config_ipaddr(adapter, pos->ip_addr, ip_event); |
3242 | } | 3253 | } |
3243 | } | 3254 | } |
3244 | 3255 | ||
3256 | static inline bool | ||
3257 | netxen_config_checkdev(struct net_device *dev) | ||
3258 | { | ||
3259 | struct netxen_adapter *adapter; | ||
3260 | |||
3261 | if (!is_netxen_netdev(dev)) | ||
3262 | return false; | ||
3263 | adapter = netdev_priv(dev); | ||
3264 | if (!adapter) | ||
3265 | return false; | ||
3266 | if (!netxen_destip_supported(adapter)) | ||
3267 | return false; | ||
3268 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
3269 | return false; | ||
3270 | |||
3271 | return true; | ||
3272 | } | ||
3273 | |||
3274 | /** | ||
3275 | * netxen_config_master - configure addresses based on master | ||
3276 | * @dev: netxen device | ||
3277 | * @event: netdev event | ||
3278 | */ | ||
3279 | static void netxen_config_master(struct net_device *dev, unsigned long event) | ||
3280 | { | ||
3281 | struct net_device *master, *slave; | ||
3282 | struct netxen_adapter *adapter = netdev_priv(dev); | ||
3283 | |||
3284 | rcu_read_lock(); | ||
3285 | master = netdev_master_upper_dev_get_rcu(dev); | ||
3286 | /* | ||
3287 | * This is the case where the netxen nic is being | ||
3288 | * enslaved and is dev_open()ed in bond_enslave() | ||
3289 | * Now we should program the bond's (and its vlans') | ||
3290 | * addresses in the netxen NIC. | ||
3291 | */ | ||
3292 | if (master && netif_is_bond_master(master) && | ||
3293 | !netif_is_bond_slave(dev)) { | ||
3294 | netxen_config_indev_addr(adapter, master, event); | ||
3295 | for_each_netdev_rcu(&init_net, slave) | ||
3296 | if (slave->priv_flags & IFF_802_1Q_VLAN && | ||
3297 | vlan_dev_real_dev(slave) == master) | ||
3298 | netxen_config_indev_addr(adapter, slave, event); | ||
3299 | } | ||
3300 | rcu_read_unlock(); | ||
3301 | /* | ||
3302 | * This is the case where the netxen nic is being | ||
3303 | * released and is dev_close()ed in bond_release() | ||
3304 | * just before IFF_BONDING is stripped. | ||
3305 | */ | ||
3306 | if (!master && dev->priv_flags & IFF_BONDING) | ||
3307 | netxen_free_ip_list(adapter, true); | ||
3308 | } | ||
3309 | |||
3245 | static int netxen_netdev_event(struct notifier_block *this, | 3310 | static int netxen_netdev_event(struct notifier_block *this, |
3246 | unsigned long event, void *ptr) | 3311 | unsigned long event, void *ptr) |
3247 | { | 3312 | { |
3248 | struct netxen_adapter *adapter; | 3313 | struct netxen_adapter *adapter; |
3249 | struct net_device *dev = (struct net_device *)ptr; | 3314 | struct net_device *dev = (struct net_device *)ptr; |
3250 | struct net_device *orig_dev = dev; | 3315 | struct net_device *orig_dev = dev; |
3316 | struct net_device *slave; | ||
3251 | 3317 | ||
3252 | recheck: | 3318 | recheck: |
3253 | if (dev == NULL) | 3319 | if (dev == NULL) |
@@ -3257,19 +3323,28 @@ recheck: | |||
3257 | dev = vlan_dev_real_dev(dev); | 3323 | dev = vlan_dev_real_dev(dev); |
3258 | goto recheck; | 3324 | goto recheck; |
3259 | } | 3325 | } |
3260 | 3326 | if (event == NETDEV_UP || event == NETDEV_DOWN) { | |
3261 | if (!is_netxen_netdev(dev)) | 3327 | /* If this is a bonding device, look for netxen-based slaves*/ |
3262 | goto done; | 3328 | if (netif_is_bond_master(dev)) { |
3263 | 3329 | rcu_read_lock(); | |
3264 | adapter = netdev_priv(dev); | 3330 | for_each_netdev_in_bond_rcu(dev, slave) { |
3265 | 3331 | if (!netxen_config_checkdev(slave)) | |
3266 | if (!adapter) | 3332 | continue; |
3267 | goto done; | 3333 | adapter = netdev_priv(slave); |
3268 | 3334 | netxen_config_indev_addr(adapter, | |
3269 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | 3335 | orig_dev, event); |
3270 | goto done; | 3336 | } |
3271 | 3337 | rcu_read_unlock(); | |
3272 | netxen_config_indev_addr(adapter, orig_dev, event); | 3338 | } else { |
3339 | if (!netxen_config_checkdev(dev)) | ||
3340 | goto done; | ||
3341 | adapter = netdev_priv(dev); | ||
3342 | /* Act only if the actual netxen is the target */ | ||
3343 | if (orig_dev == dev) | ||
3344 | netxen_config_master(dev, event); | ||
3345 | netxen_config_indev_addr(adapter, orig_dev, event); | ||
3346 | } | ||
3347 | } | ||
3273 | done: | 3348 | done: |
3274 | return NOTIFY_DONE; | 3349 | return NOTIFY_DONE; |
3275 | } | 3350 | } |
@@ -3279,12 +3354,12 @@ netxen_inetaddr_event(struct notifier_block *this, | |||
3279 | unsigned long event, void *ptr) | 3354 | unsigned long event, void *ptr) |
3280 | { | 3355 | { |
3281 | struct netxen_adapter *adapter; | 3356 | struct netxen_adapter *adapter; |
3282 | struct net_device *dev; | 3357 | struct net_device *dev, *slave; |
3283 | |||
3284 | struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; | 3358 | struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; |
3359 | unsigned long ip_event; | ||
3285 | 3360 | ||
3286 | dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; | 3361 | dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; |
3287 | 3362 | ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN; | |
3288 | recheck: | 3363 | recheck: |
3289 | if (dev == NULL) | 3364 | if (dev == NULL) |
3290 | goto done; | 3365 | goto done; |
@@ -3293,31 +3368,24 @@ recheck: | |||
3293 | dev = vlan_dev_real_dev(dev); | 3368 | dev = vlan_dev_real_dev(dev); |
3294 | goto recheck; | 3369 | goto recheck; |
3295 | } | 3370 | } |
3296 | 3371 | if (event == NETDEV_UP || event == NETDEV_DOWN) { | |
3297 | if (!is_netxen_netdev(dev)) | 3372 | /* If this is a bonding device, look for netxen-based slaves*/ |
3298 | goto done; | 3373 | if (netif_is_bond_master(dev)) { |
3299 | 3374 | rcu_read_lock(); | |
3300 | adapter = netdev_priv(dev); | 3375 | for_each_netdev_in_bond_rcu(dev, slave) { |
3301 | 3376 | if (!netxen_config_checkdev(slave)) | |
3302 | if (!adapter || !netxen_destip_supported(adapter)) | 3377 | continue; |
3303 | goto done; | 3378 | adapter = netdev_priv(slave); |
3304 | 3379 | netxen_list_config_ip(adapter, ifa, ip_event); | |
3305 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | 3380 | } |
3306 | goto done; | 3381 | rcu_read_unlock(); |
3307 | 3382 | } else { | |
3308 | switch (event) { | 3383 | if (!netxen_config_checkdev(dev)) |
3309 | case NETDEV_UP: | 3384 | goto done; |
3310 | netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP); | 3385 | adapter = netdev_priv(dev); |
3311 | netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP); | 3386 | netxen_list_config_ip(adapter, ifa, ip_event); |
3312 | break; | 3387 | } |
3313 | case NETDEV_DOWN: | ||
3314 | netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN); | ||
3315 | netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN); | ||
3316 | break; | ||
3317 | default: | ||
3318 | break; | ||
3319 | } | 3388 | } |
3320 | |||
3321 | done: | 3389 | done: |
3322 | return NOTIFY_DONE; | 3390 | return NOTIFY_DONE; |
3323 | } | 3391 | } |
@@ -3334,7 +3402,7 @@ static void | |||
3334 | netxen_restore_indev_addr(struct net_device *dev, unsigned long event) | 3402 | netxen_restore_indev_addr(struct net_device *dev, unsigned long event) |
3335 | { } | 3403 | { } |
3336 | static void | 3404 | static void |
3337 | netxen_free_vlan_ip_list(struct netxen_adapter *adapter) | 3405 | netxen_free_ip_list(struct netxen_adapter *adapter, bool master) |
3338 | { } | 3406 | { } |
3339 | #endif | 3407 | #endif |
3340 | 3408 | ||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e1ebeffa6b35..9fc1ab0c8914 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1617,6 +1617,9 @@ extern seqcount_t devnet_rename_seq; /* Device rename seq */ | |||
1617 | list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) | 1617 | list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) |
1618 | #define for_each_netdev_continue_rcu(net, d) \ | 1618 | #define for_each_netdev_continue_rcu(net, d) \ |
1619 | list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list) | 1619 | list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list) |
1620 | #define for_each_netdev_in_bond_rcu(bond, slave) \ | ||
1621 | for_each_netdev_rcu(&init_net, slave) \ | ||
1622 | if (netdev_master_upper_dev_get_rcu(slave) == bond) | ||
1620 | #define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) | 1623 | #define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) |
1621 | 1624 | ||
1622 | static inline struct net_device *next_net_device(struct net_device *dev) | 1625 | static inline struct net_device *next_net_device(struct net_device *dev) |
@@ -2774,6 +2777,11 @@ static inline void netif_set_gso_max_size(struct net_device *dev, | |||
2774 | dev->gso_max_size = size; | 2777 | dev->gso_max_size = size; |
2775 | } | 2778 | } |
2776 | 2779 | ||
2780 | static inline bool netif_is_bond_master(struct net_device *dev) | ||
2781 | { | ||
2782 | return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING; | ||
2783 | } | ||
2784 | |||
2777 | static inline bool netif_is_bond_slave(struct net_device *dev) | 2785 | static inline bool netif_is_bond_slave(struct net_device *dev) |
2778 | { | 2786 | { |
2779 | return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; | 2787 | return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; |