From 2b7b07e025b7d620a1debf5adf4c6d251512cf38 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 5 Mar 2009 13:13:30 -0800 Subject: [PATCH] datapath: Fix querying the local port by name. Before, this would return an ENOENT error. --- datapath/datapath.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index 9581e792..85f5a6a6 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -354,6 +354,16 @@ static int new_nbp(struct datapath *dp, struct net_device *dev, int port_no) p->dev = dev; if (port_no != ODPP_LOCAL) rcu_assign_pointer(dev->br_port, p); + else { + /* For consistency it would make sense to assign dev->br_port + * here too, but we can't because that would cause packets + * received on the local port to get caught in + * dp_frame_hook(). On modern Linux kernels that's not a big + * deal--we would just return an appropriate value--but on + * Linux 2.4 there's no way for the frame hook to pass along + * the skbuff to the rest of the network stack. So we're + * stuck with the status quo. */ + } rcu_assign_pointer(dp->ports[port_no], p); list_add_rcu(&p->node, &dp->port_list); dp->n_ports++; @@ -1140,7 +1150,6 @@ query_port(struct datapath *dp, struct odp_port __user *uport) if (copy_from_user(&port, uport, sizeof port)) return -EFAULT; if (port.devname[0]) { - struct net_bridge_port *p; struct net_device *dev; int err; @@ -1150,8 +1159,12 @@ query_port(struct datapath *dp, struct odp_port __user *uport) if (!dev) return -ENODEV; - p = dev->br_port; - err = p && p->dp == dp ? put_port(p, uport) : -ENOENT; + if (dev == dp->ports[ODPP_LOCAL]->dev) { + err = put_port(dp->ports[ODPP_LOCAL], uport); + } else { + struct net_bridge_port *p = dev->br_port; + err = p && p->dp == dp ? put_port(p, uport) : -ENOENT; + } dev_put(dev); return err; -- 2.30.2