aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2009-08-19 12:51:27 -0700
committerBen Pfaff <blp@nicira.com>2009-08-19 13:44:05 -0700
commitb78a7336a3318a3c348004760bac3e0057b9e9d1 (patch)
treec1ce6fe32fd0aeb6db50858601e55b0227cf2633
parentaf616f686b851c7e31ee48f16e7ae7df6f550553 (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.c9
-rw-r--r--datapath/dp_notify.c9
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;