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.
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;
}
#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)
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;