lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 25 Nov 2014 11:28:48 +0100 From: Jiri Pirko <jiri@...nulli.us> To: netdev@...r.kernel.org Cc: davem@...emloft.net, nhorman@...driver.com, andy@...yhouse.net, tgraf@...g.ch, dborkman@...hat.com, ogerlitz@...lanox.com, jesse@...ira.com, pshelar@...ira.com, azhou@...ira.com, ben@...adent.org.uk, stephen@...workplumber.org, jeffrey.t.kirsher@...el.com, vyasevic@...hat.com, xiyou.wangcong@...il.com, john.r.fastabend@...el.com, edumazet@...gle.com, jhs@...atatu.com, sfeldma@...il.com, f.fainelli@...il.com, roopa@...ulusnetworks.com, linville@...driver.com, jasowang@...hat.com, ebiederm@...ssion.com, nicolas.dichtel@...nd.com, ryazanov.s.a@...il.com, buytenh@...tstofly.org, aviadr@...lanox.com, nbd@...nwrt.org, alexei.starovoitov@...il.com, Neil.Jerram@...aswitch.com, ronye@...lanox.com, simon.horman@...ronome.com, alexander.h.duyck@...hat.com, john.ronciak@...el.com, mleitner@...hat.com, shrijeet@...il.com, gospo@...ulusnetworks.com, bcrl@...ck.org Subject: [patch net-next v3 17/17] rocker: add ndo_bridge_setlnk/getlink support for learning policy From: Scott Feldman <sfeldma@...il.com> Rocker ports will use new "swdev" hwmode for bridge port offload policy. Current supported policy settings are BR_LEARNING and BR_LEARNING_SYNC. User can turn on/off device port FDB learning and syncing to bridge. Signed-off-by: Scott Feldman <sfeldma@...il.com> Signed-off-by: Jiri Pirko <jiri@...nulli.us> --- new in v3 --- drivers/net/ethernet/rocker/rocker.c | 99 ++++++++++++++++++++++++++++++++++++ drivers/net/ethernet/rocker/rocker.h | 1 + 2 files changed, 100 insertions(+) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index 1434497..6d56960 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -203,6 +203,7 @@ struct rocker_port { u32 lport; __be16 internal_vlan_id; int stp_state; + u32 brport_flags; bool ctrls[ROCKER_CTRL_MAX]; unsigned long vlan_bitmap[ROCKER_VLAN_BITMAP_LEN]; struct napi_struct napi_tx; @@ -1629,6 +1630,30 @@ rocker_cmd_set_port_settings_macaddr_prep(struct rocker *rocker, return 0; } +static int +rocker_cmd_set_port_learning_prep(struct rocker *rocker, + struct rocker_port *rocker_port, + struct rocker_desc_info *desc_info, + void *priv) +{ + struct rocker_tlv *cmd_info; + + if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, + ROCKER_TLV_CMD_TYPE_SET_PORT_SETTINGS)) + return -EMSGSIZE; + cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO); + if (!cmd_info) + return -EMSGSIZE; + if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_CMD_PORT_SETTINGS_LPORT, + rocker_port->lport)) + return -EMSGSIZE; + if (rocker_tlv_put_u8(desc_info, ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING, + !!(rocker_port->brport_flags & BR_LEARNING))) + return -EMSGSIZE; + rocker_tlv_nest_end(desc_info, cmd_info); + return 0; +} + static int rocker_cmd_get_port_settings_ethtool(struct rocker_port *rocker_port, struct ethtool_cmd *ecmd) { @@ -1663,6 +1688,13 @@ static int rocker_cmd_set_port_settings_macaddr(struct rocker_port *rocker_port, macaddr, NULL, NULL, false); } +static int rocker_port_set_learning(struct rocker_port *rocker_port) +{ + return rocker_cmd_exec(rocker_port->rocker, rocker_port, + rocker_cmd_set_port_learning_prep, + NULL, NULL, NULL, false); +} + static int rocker_cmd_flow_tbl_add_ig_port(struct rocker_desc_info *desc_info, struct rocker_flow_tbl_entry *entry) { @@ -2995,6 +3027,7 @@ static int rocker_port_fdb_learn(struct rocker_port *rocker_port, u32 out_lport = rocker_port->lport; u32 tunnel_id = 0; u32 group_id = ROCKER_GROUP_NONE; + bool syncing = !!(rocker_port->brport_flags & BR_LEARNING_SYNC); bool copy_to_cpu = false; int err; @@ -3009,6 +3042,9 @@ static int rocker_port_fdb_learn(struct rocker_port *rocker_port, return err; } + if (!syncing) + return 0; + if (!rocker_port_is_bridged(rocker_port)) return 0; @@ -3657,6 +3693,64 @@ skip: return idx; } +static int rocker_port_bridge_setlink(struct net_device *dev, + struct nlmsghdr *nlh) +{ + struct rocker_port *rocker_port = netdev_priv(dev); + struct nlattr *protinfo; + struct nlattr *afspec; + struct nlattr *attr; + u16 mode; + int err; + + protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), + IFLA_PROTINFO); + afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); + + if (afspec) { + attr = nla_find_nested(afspec, IFLA_BRIDGE_MODE); + if (attr) { + mode = nla_get_u16(attr); + if (mode != BRIDGE_MODE_SWDEV) + return -EINVAL; + } + } + + if (protinfo) { + attr = nla_find_nested(protinfo, IFLA_BRPORT_LEARNING); + if (attr) { + if (nla_get_u8(attr)) + rocker_port->brport_flags |= BR_LEARNING; + else + rocker_port->brport_flags &= ~BR_LEARNING; + err = rocker_port_set_learning(rocker_port); + if (err) + return err; + } + attr = nla_find_nested(protinfo, IFLA_BRPORT_LEARNING_SYNC); + if (attr) { + if (nla_get_u8(attr)) + rocker_port->brport_flags |= BR_LEARNING_SYNC; + else + rocker_port->brport_flags &= ~BR_LEARNING_SYNC; + } + } + + return 0; +} + +static int rocker_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, + struct net_device *dev, + u32 filter_mask) +{ + struct rocker_port *rocker_port = netdev_priv(dev); + u16 mode = BRIDGE_MODE_SWDEV; + u32 mask = BR_LEARNING | BR_LEARNING_SYNC; + + return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, + rocker_port->brport_flags, mask); +} + static int rocker_port_switch_parent_id_get(struct net_device *dev, struct netdev_phys_item_id *psid) { @@ -3685,6 +3779,8 @@ static const struct net_device_ops rocker_port_netdev_ops = { .ndo_fdb_add = rocker_port_fdb_add, .ndo_fdb_del = rocker_port_fdb_del, .ndo_fdb_dump = rocker_port_fdb_dump, + .ndo_bridge_setlink = rocker_port_bridge_setlink, + .ndo_bridge_getlink = rocker_port_bridge_getlink, .ndo_switch_parent_id_get = rocker_port_switch_parent_id_get, .ndo_switch_port_stp_update = rocker_port_switch_port_stp_update, }; @@ -3885,6 +3981,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number) rocker_port->rocker = rocker; rocker_port->port_number = port_number; rocker_port->lport = port_number + 1; + rocker_port->brport_flags = BR_LEARNING | BR_LEARNING_SYNC; rocker_port_dev_addr_init(rocker, rocker_port); dev->netdev_ops = &rocker_port_netdev_ops; @@ -3904,6 +4001,8 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number) } rocker->ports[port_number] = rocker_port; + rocker_port_set_learning(rocker_port); + rocker_port->internal_vlan_id = rocker_port_internal_vlan_id_get(rocker_port, dev->ifindex); err = rocker_port_ig_tbl(rocker_port, 0); diff --git a/drivers/net/ethernet/rocker/rocker.h b/drivers/net/ethernet/rocker/rocker.h index 5251cf8..8d2865b 100644 --- a/drivers/net/ethernet/rocker/rocker.h +++ b/drivers/net/ethernet/rocker/rocker.h @@ -139,6 +139,7 @@ enum { ROCKER_TLV_CMD_PORT_SETTINGS_AUTONEG, /* u8 */ ROCKER_TLV_CMD_PORT_SETTINGS_MACADDR, /* binary */ ROCKER_TLV_CMD_PORT_SETTINGS_MODE, /* u8 */ + ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING, /* u8 */ __ROCKER_TLV_CMD_PORT_SETTINGS_MAX, ROCKER_TLV_CMD_PORT_SETTINGS_MAX = -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists