diff options
author | Ben Pfaff <blp@nicira.com> | 2009-08-19 12:51:27 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2009-08-19 13:44:05 -0700 |
commit | b78a7336a3318a3c348004760bac3e0057b9e9d1 (patch) | |
tree | c1ce6fe32fd0aeb6db50858601e55b0227cf2633 | |
parent | af616f686b851c7e31ee48f16e7ae7df6f550553 (diff) |
datapath: Additional fixes for datapath device renaming.
Commit c874dc6d6b "secchan: Fix behavior when a network device is renamed."
fixed a crash in the datapath when network devices within a datapath were
renamed. However, this missed the case where the device that was renamed
was a datapath's internal port: these devices have their br_port members
set to NULL, so we have to determine that they belong to a datapath another
way. This commit does so.
This commit also changes the initialization order in dp_dev_create().
Otherwise, dp_device_event() will dereference null when it is called via
register_netdevice(), because the newly created device is a datapath device
but its members are not yet initialized.
-rw-r--r-- | datapath/dp_dev.c | 9 | ||||
-rw-r--r-- | datapath/dp_notify.c | 9 |
2 files changed, 12 insertions, 6 deletions
diff --git a/datapath/dp_dev.c b/datapath/dp_dev.c index d11e7f6f..b0ba3017 100644 --- a/datapath/dp_dev.c +++ b/datapath/dp_dev.c @@ -211,16 +211,17 @@ struct net_device *dp_dev_create(struct datapath *dp, const char *dp_name, int p if (!netdev) return ERR_PTR(-ENOMEM); + dp_dev = dp_dev_priv(netdev); + dp_dev->dp = dp; + dp_dev->port_no = port_no; + dp_dev->dev = netdev; + err = register_netdevice(netdev); if (err) { free_netdev(netdev); return ERR_PTR(err); } - dp_dev = dp_dev_priv(netdev); - dp_dev->dp = dp; - dp_dev->port_no = port_no; - dp_dev->dev = netdev; return netdev; } diff --git a/datapath/dp_notify.c b/datapath/dp_notify.c index f22d8b34..d5a27498 100644 --- a/datapath/dp_notify.c +++ b/datapath/dp_notify.c @@ -11,7 +11,7 @@ #include <linux/netdevice.h> #include "datapath.h" - +#include "dp_dev.h" static int dp_device_event(struct notifier_block *unused, unsigned long event, void *ptr) @@ -20,7 +20,12 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event, struct net_bridge_port *p; struct datapath *dp; - p = dev->br_port; + if (is_dp_dev(dev)) { + struct dp_dev *dp_dev = dp_dev_priv(dev); + p = dp_dev->dp->ports[dp_dev->port_no]; + } else { + p = dev->br_port; + } if (!p) return NOTIFY_DONE; dp = p->dp; |