mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
switchdev: convert parent_id_get to switchdev attr get
Switch ID is just a gettable port attribute. Convert switchdev op switchdev_parent_id_get to a switchdev attr. Note: for sysfs and netlink interfaces, SWITCHDEV_ATTR_PORT_PARENT_ID is called with SWITCHDEV_F_NO_RECUSE to limit switch ID user-visiblity to only port netdevs. So when a port is stacked under bond/bridge, the user can only query switch id via the switch ports, but not via the upper devices Signed-off-by: Scott Feldman <sfeldma@gmail.com> Acked-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3094333d90
commit
f8e20a9f87
@ -4221,14 +4221,21 @@ static const struct net_device_ops rocker_port_netdev_ops = {
|
|||||||
* swdev interface
|
* swdev interface
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
static int rocker_port_switchdev_parent_id_get(struct net_device *dev,
|
static int rocker_port_attr_get(struct net_device *dev,
|
||||||
struct netdev_phys_item_id *psid)
|
struct switchdev_attr *attr)
|
||||||
{
|
{
|
||||||
struct rocker_port *rocker_port = netdev_priv(dev);
|
struct rocker_port *rocker_port = netdev_priv(dev);
|
||||||
struct rocker *rocker = rocker_port->rocker;
|
struct rocker *rocker = rocker_port->rocker;
|
||||||
|
|
||||||
psid->id_len = sizeof(rocker->hw.id);
|
switch (attr->id) {
|
||||||
memcpy(&psid->id, &rocker->hw.id, psid->id_len);
|
case SWITCHDEV_ATTR_PORT_PARENT_ID:
|
||||||
|
attr->ppid.id_len = sizeof(rocker->hw.id);
|
||||||
|
memcpy(&attr->ppid.id, &rocker->hw.id, attr->ppid.id_len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4266,7 +4273,7 @@ static int rocker_port_switchdev_fib_ipv4_del(struct net_device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct switchdev_ops rocker_port_switchdev_ops = {
|
static const struct switchdev_ops rocker_port_switchdev_ops = {
|
||||||
.switchdev_parent_id_get = rocker_port_switchdev_parent_id_get,
|
.switchdev_port_attr_get = rocker_port_attr_get,
|
||||||
.switchdev_port_stp_update = rocker_port_switchdev_port_stp_update,
|
.switchdev_port_stp_update = rocker_port_switchdev_port_stp_update,
|
||||||
.switchdev_fib_ipv4_add = rocker_port_switchdev_fib_ipv4_add,
|
.switchdev_fib_ipv4_add = rocker_port_switchdev_fib_ipv4_add,
|
||||||
.switchdev_fib_ipv4_del = rocker_port_switchdev_fib_ipv4_del,
|
.switchdev_fib_ipv4_del = rocker_port_switchdev_fib_ipv4_del,
|
||||||
|
@ -25,12 +25,16 @@ enum switchdev_trans {
|
|||||||
|
|
||||||
enum switchdev_attr_id {
|
enum switchdev_attr_id {
|
||||||
SWITCHDEV_ATTR_UNDEFINED,
|
SWITCHDEV_ATTR_UNDEFINED,
|
||||||
|
SWITCHDEV_ATTR_PORT_PARENT_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct switchdev_attr {
|
struct switchdev_attr {
|
||||||
enum switchdev_attr_id id;
|
enum switchdev_attr_id id;
|
||||||
enum switchdev_trans trans;
|
enum switchdev_trans trans;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
union {
|
||||||
|
struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fib_info;
|
struct fib_info;
|
||||||
@ -38,10 +42,6 @@ struct fib_info;
|
|||||||
/**
|
/**
|
||||||
* struct switchdev_ops - switchdev operations
|
* struct switchdev_ops - switchdev operations
|
||||||
*
|
*
|
||||||
* @switchdev_parent_id_get: Called to get an ID of the switch chip this port
|
|
||||||
* is part of. If driver implements this, it indicates that it
|
|
||||||
* represents a port of a switch chip.
|
|
||||||
*
|
|
||||||
* @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
|
* @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
|
||||||
*
|
*
|
||||||
* @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
|
* @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
|
||||||
@ -54,8 +54,6 @@ struct fib_info;
|
|||||||
* @switchdev_fib_ipv4_del: Called to delete IPv4 route from switch device.
|
* @switchdev_fib_ipv4_del: Called to delete IPv4 route from switch device.
|
||||||
*/
|
*/
|
||||||
struct switchdev_ops {
|
struct switchdev_ops {
|
||||||
int (*switchdev_parent_id_get)(struct net_device *dev,
|
|
||||||
struct netdev_phys_item_id *psid);
|
|
||||||
int (*switchdev_port_attr_get)(struct net_device *dev,
|
int (*switchdev_port_attr_get)(struct net_device *dev,
|
||||||
struct switchdev_attr *attr);
|
struct switchdev_attr *attr);
|
||||||
int (*switchdev_port_attr_set)(struct net_device *dev,
|
int (*switchdev_port_attr_set)(struct net_device *dev,
|
||||||
@ -93,8 +91,6 @@ switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_SWITCHDEV
|
#ifdef CONFIG_NET_SWITCHDEV
|
||||||
|
|
||||||
int switchdev_parent_id_get(struct net_device *dev,
|
|
||||||
struct netdev_phys_item_id *psid);
|
|
||||||
int switchdev_port_attr_get(struct net_device *dev,
|
int switchdev_port_attr_get(struct net_device *dev,
|
||||||
struct switchdev_attr *attr);
|
struct switchdev_attr *attr);
|
||||||
int switchdev_port_attr_set(struct net_device *dev,
|
int switchdev_port_attr_set(struct net_device *dev,
|
||||||
@ -120,12 +116,6 @@ void switchdev_fib_ipv4_abort(struct fib_info *fi);
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int switchdev_parent_id_get(struct net_device *dev,
|
|
||||||
struct netdev_phys_item_id *psid)
|
|
||||||
{
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int switchdev_port_attr_get(struct net_device *dev,
|
static inline int switchdev_port_attr_get(struct net_device *dev,
|
||||||
struct switchdev_attr *attr)
|
struct switchdev_attr *attr)
|
||||||
{
|
{
|
||||||
|
@ -458,11 +458,15 @@ static ssize_t phys_switch_id_show(struct device *dev,
|
|||||||
return restart_syscall();
|
return restart_syscall();
|
||||||
|
|
||||||
if (dev_isalive(netdev)) {
|
if (dev_isalive(netdev)) {
|
||||||
struct netdev_phys_item_id ppid;
|
struct switchdev_attr attr = {
|
||||||
|
.id = SWITCHDEV_ATTR_PORT_PARENT_ID,
|
||||||
|
.flags = SWITCHDEV_F_NO_RECURSE,
|
||||||
|
};
|
||||||
|
|
||||||
ret = switchdev_parent_id_get(netdev, &ppid);
|
ret = switchdev_port_attr_get(netdev, &attr);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = sprintf(buf, "%*phN\n", ppid.id_len, ppid.id);
|
ret = sprintf(buf, "%*phN\n", attr.ppid.id_len,
|
||||||
|
attr.ppid.id);
|
||||||
}
|
}
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
|
@ -1004,16 +1004,19 @@ static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev)
|
|||||||
static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
|
static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct netdev_phys_item_id psid;
|
struct switchdev_attr attr = {
|
||||||
|
.id = SWITCHDEV_ATTR_PORT_PARENT_ID,
|
||||||
|
.flags = SWITCHDEV_F_NO_RECURSE,
|
||||||
|
};
|
||||||
|
|
||||||
err = switchdev_parent_id_get(dev, &psid);
|
err = switchdev_port_attr_get(dev, &attr);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == -EOPNOTSUPP)
|
if (err == -EOPNOTSUPP)
|
||||||
return 0;
|
return 0;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nla_put(skb, IFLA_PHYS_SWITCH_ID, psid.id_len, psid.id))
|
if (nla_put(skb, IFLA_PHYS_SWITCH_ID, attr.ppid.id_len, attr.ppid.id))
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -382,14 +382,20 @@ static int dsa_slave_bridge_port_leave(struct net_device *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsa_slave_parent_id_get(struct net_device *dev,
|
static int dsa_slave_port_attr_get(struct net_device *dev,
|
||||||
struct netdev_phys_item_id *psid)
|
struct switchdev_attr *attr)
|
||||||
{
|
{
|
||||||
struct dsa_slave_priv *p = netdev_priv(dev);
|
struct dsa_slave_priv *p = netdev_priv(dev);
|
||||||
struct dsa_switch *ds = p->parent;
|
struct dsa_switch *ds = p->parent;
|
||||||
|
|
||||||
psid->id_len = sizeof(ds->index);
|
switch (attr->id) {
|
||||||
memcpy(&psid->id, &ds->index, psid->id_len);
|
case SWITCHDEV_ATTR_PORT_PARENT_ID:
|
||||||
|
attr->ppid.id_len = sizeof(ds->index);
|
||||||
|
memcpy(&attr->ppid.id, &ds->index, attr->ppid.id_len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -676,7 +682,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct switchdev_ops dsa_slave_switchdev_ops = {
|
static const struct switchdev_ops dsa_slave_switchdev_ops = {
|
||||||
.switchdev_parent_id_get = dsa_slave_parent_id_get,
|
.switchdev_port_attr_get = dsa_slave_port_attr_get,
|
||||||
.switchdev_port_stp_update = dsa_slave_stp_update,
|
.switchdev_port_stp_update = dsa_slave_stp_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,24 +18,6 @@
|
|||||||
#include <net/ip_fib.h>
|
#include <net/ip_fib.h>
|
||||||
#include <net/switchdev.h>
|
#include <net/switchdev.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* switchdev_parent_id_get - Get ID of a switch
|
|
||||||
* @dev: port device
|
|
||||||
* @psid: switch ID
|
|
||||||
*
|
|
||||||
* Get ID of a switch this port is part of.
|
|
||||||
*/
|
|
||||||
int switchdev_parent_id_get(struct net_device *dev,
|
|
||||||
struct netdev_phys_item_id *psid)
|
|
||||||
{
|
|
||||||
const struct switchdev_ops *ops = dev->switchdev_ops;
|
|
||||||
|
|
||||||
if (!ops || !ops->switchdev_parent_id_get)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
return ops->switchdev_parent_id_get(dev, psid);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(switchdev_parent_id_get);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* switchdev_port_attr_get - Get port attribute
|
* switchdev_port_attr_get - Get port attribute
|
||||||
*
|
*
|
||||||
@ -414,11 +396,10 @@ static struct net_device *switchdev_get_lowest_dev(struct net_device *dev)
|
|||||||
struct list_head *iter;
|
struct list_head *iter;
|
||||||
|
|
||||||
/* Recusively search down until we find a sw port dev.
|
/* Recusively search down until we find a sw port dev.
|
||||||
* (A sw port dev supports switchdev_parent_id_get).
|
* (A sw port dev supports switchdev_port_attr_get).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (dev->features & NETIF_F_HW_SWITCH_OFFLOAD &&
|
if (ops && ops->switchdev_port_attr_get)
|
||||||
ops && ops->switchdev_parent_id_get)
|
|
||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
netdev_for_each_lower_dev(dev, lower_dev, iter) {
|
netdev_for_each_lower_dev(dev, lower_dev, iter) {
|
||||||
@ -432,8 +413,10 @@ static struct net_device *switchdev_get_lowest_dev(struct net_device *dev)
|
|||||||
|
|
||||||
static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
|
static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
|
||||||
{
|
{
|
||||||
struct netdev_phys_item_id psid;
|
struct switchdev_attr attr = {
|
||||||
struct netdev_phys_item_id prev_psid;
|
.id = SWITCHDEV_ATTR_PORT_PARENT_ID,
|
||||||
|
};
|
||||||
|
struct switchdev_attr prev_attr;
|
||||||
struct net_device *dev = NULL;
|
struct net_device *dev = NULL;
|
||||||
int nhsel;
|
int nhsel;
|
||||||
|
|
||||||
@ -449,17 +432,18 @@ static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
|
|||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (switchdev_parent_id_get(dev, &psid))
|
if (switchdev_port_attr_get(dev, &attr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (nhsel > 0) {
|
if (nhsel > 0) {
|
||||||
if (prev_psid.id_len != psid.id_len)
|
if (prev_attr.ppid.id_len != attr.ppid.id_len)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (memcmp(prev_psid.id, psid.id, psid.id_len))
|
if (memcmp(prev_attr.ppid.id, attr.ppid.id,
|
||||||
|
attr.ppid.id_len))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_psid = psid;
|
prev_attr = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
|
Loading…
Reference in New Issue
Block a user