aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2016-08-12 10:10:32 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-13 18:15:54 -0400
commite20038724552cd05e351cd7d7526d646953d26b7 (patch)
tree15cd8bf0e03c5dbf96762bedbfb3cccf4613a477
parentbc561632dddd5af0c4444d919f01cbf6d553aa0a (diff)
macsec: fix lockdep splats when nesting devices
Currently, trying to setup a vlan over a macsec device, or other combinations of devices, triggers a lockdep warning. Use netdev_lockdep_set_classes and ndo_get_lock_subclass, similar to what macvlan does. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/macsec.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index dbd590a8177f..2043e8c97a81 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -270,6 +270,7 @@ struct macsec_dev {
270 struct pcpu_secy_stats __percpu *stats; 270 struct pcpu_secy_stats __percpu *stats;
271 struct list_head secys; 271 struct list_head secys;
272 struct gro_cells gro_cells; 272 struct gro_cells gro_cells;
273 unsigned int nest_level;
273}; 274};
274 275
275/** 276/**
@@ -2699,6 +2700,8 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
2699 2700
2700#define MACSEC_FEATURES \ 2701#define MACSEC_FEATURES \
2701 (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) 2702 (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
2703static struct lock_class_key macsec_netdev_addr_lock_key;
2704
2702static int macsec_dev_init(struct net_device *dev) 2705static int macsec_dev_init(struct net_device *dev)
2703{ 2706{
2704 struct macsec_dev *macsec = macsec_priv(dev); 2707 struct macsec_dev *macsec = macsec_priv(dev);
@@ -2910,6 +2913,13 @@ static int macsec_get_iflink(const struct net_device *dev)
2910 return macsec_priv(dev)->real_dev->ifindex; 2913 return macsec_priv(dev)->real_dev->ifindex;
2911} 2914}
2912 2915
2916
2917static int macsec_get_nest_level(struct net_device *dev)
2918{
2919 return macsec_priv(dev)->nest_level;
2920}
2921
2922
2913static const struct net_device_ops macsec_netdev_ops = { 2923static const struct net_device_ops macsec_netdev_ops = {
2914 .ndo_init = macsec_dev_init, 2924 .ndo_init = macsec_dev_init,
2915 .ndo_uninit = macsec_dev_uninit, 2925 .ndo_uninit = macsec_dev_uninit,
@@ -2923,6 +2933,7 @@ static const struct net_device_ops macsec_netdev_ops = {
2923 .ndo_start_xmit = macsec_start_xmit, 2933 .ndo_start_xmit = macsec_start_xmit,
2924 .ndo_get_stats64 = macsec_get_stats64, 2934 .ndo_get_stats64 = macsec_get_stats64,
2925 .ndo_get_iflink = macsec_get_iflink, 2935 .ndo_get_iflink = macsec_get_iflink,
2936 .ndo_get_lock_subclass = macsec_get_nest_level,
2926}; 2937};
2927 2938
2928static const struct device_type macsec_type = { 2939static const struct device_type macsec_type = {
@@ -3050,10 +3061,12 @@ static void macsec_del_dev(struct macsec_dev *macsec)
3050static void macsec_common_dellink(struct net_device *dev, struct list_head *head) 3061static void macsec_common_dellink(struct net_device *dev, struct list_head *head)
3051{ 3062{
3052 struct macsec_dev *macsec = macsec_priv(dev); 3063 struct macsec_dev *macsec = macsec_priv(dev);
3064 struct net_device *real_dev = macsec->real_dev;
3053 3065
3054 unregister_netdevice_queue(dev, head); 3066 unregister_netdevice_queue(dev, head);
3055 list_del_rcu(&macsec->secys); 3067 list_del_rcu(&macsec->secys);
3056 macsec_del_dev(macsec); 3068 macsec_del_dev(macsec);
3069 netdev_upper_dev_unlink(real_dev, dev);
3057 3070
3058 macsec_generation++; 3071 macsec_generation++;
3059} 3072}
@@ -3188,6 +3201,16 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
3188 3201
3189 dev_hold(real_dev); 3202 dev_hold(real_dev);
3190 3203
3204 macsec->nest_level = dev_get_nest_level(real_dev, netif_is_macsec) + 1;
3205 netdev_lockdep_set_classes(dev);
3206 lockdep_set_class_and_subclass(&dev->addr_list_lock,
3207 &macsec_netdev_addr_lock_key,
3208 macsec_get_nest_level(dev));
3209
3210 err = netdev_upper_dev_link(real_dev, dev);
3211 if (err < 0)
3212 goto unregister;
3213
3191 /* need to be already registered so that ->init has run and 3214 /* need to be already registered so that ->init has run and
3192 * the MAC addr is set 3215 * the MAC addr is set
3193 */ 3216 */
@@ -3200,12 +3223,12 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
3200 3223
3201 if (rx_handler && sci_exists(real_dev, sci)) { 3224 if (rx_handler && sci_exists(real_dev, sci)) {
3202 err = -EBUSY; 3225 err = -EBUSY;
3203 goto unregister; 3226 goto unlink;
3204 } 3227 }
3205 3228
3206 err = macsec_add_dev(dev, sci, icv_len); 3229 err = macsec_add_dev(dev, sci, icv_len);
3207 if (err) 3230 if (err)
3208 goto unregister; 3231 goto unlink;
3209 3232
3210 if (data) 3233 if (data)
3211 macsec_changelink_common(dev, data); 3234 macsec_changelink_common(dev, data);
@@ -3220,6 +3243,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
3220 3243
3221del_dev: 3244del_dev:
3222 macsec_del_dev(macsec); 3245 macsec_del_dev(macsec);
3246unlink:
3247 netdev_upper_dev_unlink(real_dev, dev);
3223unregister: 3248unregister:
3224 unregister_netdevice(dev); 3249 unregister_netdevice(dev);
3225 return err; 3250 return err;