Commit ff43c28a authored by David S. Miller's avatar David S. Miller

Merge branch 'rocker-next'

Scott Feldman says:

====================
rocker: enable by default untagged VLAN support

This patch set is a followup to Simon Horman's RFC patch:

   [PATCH/RFC net-next] rocker: by default accept untagged packets

Now, on port probe, we install untagged VLAN (vid=0) support for each port
as the default.  This is equivalent to the command:

   bridge vlan add vid 0 dev DEV self

Accepting untagged VLAN pkts is a reasonable default, but the user could
override this with:

   bridge vlan del vid 0 dev DEV self

With this, we no longer need 8021q module to install vid=0 when port interface
opens.  In fact, we don't need support for legacy VLAN ndo ops at all since
they're superseded by bridge_setlink/dellink.  So remove legacy VLAN ndo ops
support in driver.  (The legacy VLAN ndo ops are supported by bonding/team
drivers, but don't fit into the transaction model offered by switchdev, so
switching all VLAN functions to bridge_setlink/dellink switchdev support gets
us stacked driver + transaction model support).
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 66e5133f 2aa2ed08
...@@ -3136,6 +3136,8 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port, ...@@ -3136,6 +3136,8 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
for (i = 0; i < rocker->port_count; i++) { for (i = 0; i < rocker->port_count; i++) {
p = rocker->ports[i]; p = rocker->ports[i];
if (!p)
continue;
if (!rocker_port_is_bridged(p)) if (!rocker_port_is_bridged(p))
continue; continue;
if (test_bit(ntohs(vlan_id), p->vlan_bitmap)) { if (test_bit(ntohs(vlan_id), p->vlan_bitmap)) {
...@@ -3195,7 +3197,7 @@ static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port, ...@@ -3195,7 +3197,7 @@ static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
for (i = 0; i < rocker->port_count; i++) { for (i = 0; i < rocker->port_count; i++) {
p = rocker->ports[i]; p = rocker->ports[i];
if (test_bit(ntohs(vlan_id), p->vlan_bitmap)) if (p && test_bit(ntohs(vlan_id), p->vlan_bitmap))
ref++; ref++;
} }
...@@ -4162,35 +4164,6 @@ static int rocker_port_set_mac_address(struct net_device *dev, void *p) ...@@ -4162,35 +4164,6 @@ static int rocker_port_set_mac_address(struct net_device *dev, void *p)
return 0; return 0;
} }
static int rocker_port_vlan_rx_add_vid(struct net_device *dev,
__be16 proto, u16 vid)
{
struct rocker_port *rocker_port = netdev_priv(dev);
int err;
err = rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, vid);
if (err)
return err;
return rocker_port_router_mac(rocker_port, SWITCHDEV_TRANS_NONE,
0, htons(vid));
}
static int rocker_port_vlan_rx_kill_vid(struct net_device *dev,
__be16 proto, u16 vid)
{
struct rocker_port *rocker_port = netdev_priv(dev);
int err;
err = rocker_port_router_mac(rocker_port, SWITCHDEV_TRANS_NONE,
ROCKER_OP_FLAG_REMOVE, htons(vid));
if (err)
return err;
return rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE,
ROCKER_OP_FLAG_REMOVE, vid);
}
static int rocker_port_get_phys_port_name(struct net_device *dev, static int rocker_port_get_phys_port_name(struct net_device *dev,
char *buf, size_t len) char *buf, size_t len)
{ {
...@@ -4211,8 +4184,6 @@ static const struct net_device_ops rocker_port_netdev_ops = { ...@@ -4211,8 +4184,6 @@ static const struct net_device_ops rocker_port_netdev_ops = {
.ndo_stop = rocker_port_stop, .ndo_stop = rocker_port_stop,
.ndo_start_xmit = rocker_port_xmit, .ndo_start_xmit = rocker_port_xmit,
.ndo_set_mac_address = rocker_port_set_mac_address, .ndo_set_mac_address = rocker_port_set_mac_address,
.ndo_vlan_rx_add_vid = rocker_port_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = rocker_port_vlan_rx_kill_vid,
.ndo_bridge_getlink = switchdev_port_bridge_getlink, .ndo_bridge_getlink = switchdev_port_bridge_getlink,
.ndo_bridge_setlink = switchdev_port_bridge_setlink, .ndo_bridge_setlink = switchdev_port_bridge_setlink,
.ndo_bridge_dellink = switchdev_port_bridge_dellink, .ndo_bridge_dellink = switchdev_port_bridge_dellink,
...@@ -4320,7 +4291,12 @@ static int rocker_port_vlan_add(struct rocker_port *rocker_port, ...@@ -4320,7 +4291,12 @@ static int rocker_port_vlan_add(struct rocker_port *rocker_port,
if (err) if (err)
return err; return err;
return rocker_port_router_mac(rocker_port, trans, 0, htons(vid)); err = rocker_port_router_mac(rocker_port, trans, 0, htons(vid));
if (err)
rocker_port_vlan(rocker_port, trans,
ROCKER_OP_FLAG_REMOVE, vid);
return err;
} }
static int rocker_port_vlans_add(struct rocker_port *rocker_port, static int rocker_port_vlans_add(struct rocker_port *rocker_port,
...@@ -4852,6 +4828,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number) ...@@ -4852,6 +4828,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
const struct pci_dev *pdev = rocker->pdev; const struct pci_dev *pdev = rocker->pdev;
struct rocker_port *rocker_port; struct rocker_port *rocker_port;
struct net_device *dev; struct net_device *dev;
u16 untagged_vid = 0;
int err; int err;
dev = alloc_etherdev(sizeof(struct rocker_port)); dev = alloc_etherdev(sizeof(struct rocker_port));
...@@ -4875,8 +4852,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number) ...@@ -4875,8 +4852,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
NAPI_POLL_WEIGHT); NAPI_POLL_WEIGHT);
rocker_carrier_init(rocker_port); rocker_carrier_init(rocker_port);
dev->features |= NETIF_F_NETNS_LOCAL | dev->features |= NETIF_F_NETNS_LOCAL;
NETIF_F_HW_VLAN_CTAG_FILTER;
err = register_netdev(dev); err = register_netdev(dev);
if (err) { if (err) {
...@@ -4887,16 +4863,27 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number) ...@@ -4887,16 +4863,27 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
rocker_port_set_learning(rocker_port, SWITCHDEV_TRANS_NONE); rocker_port_set_learning(rocker_port, SWITCHDEV_TRANS_NONE);
rocker_port->internal_vlan_id =
rocker_port_internal_vlan_id_get(rocker_port, dev->ifindex);
err = rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE, 0); err = rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE, 0);
if (err) { if (err) {
dev_err(&pdev->dev, "install ig port table failed\n"); dev_err(&pdev->dev, "install ig port table failed\n");
goto err_port_ig_tbl; goto err_port_ig_tbl;
} }
rocker_port->internal_vlan_id =
rocker_port_internal_vlan_id_get(rocker_port, dev->ifindex);
err = rocker_port_vlan_add(rocker_port, SWITCHDEV_TRANS_NONE,
untagged_vid, 0);
if (err) {
netdev_err(rocker_port->dev, "install untagged VLAN failed\n");
goto err_untagged_vlan;
}
return 0; return 0;
err_untagged_vlan:
rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE,
ROCKER_OP_FLAG_REMOVE);
err_port_ig_tbl: err_port_ig_tbl:
unregister_netdev(dev); unregister_netdev(dev);
err_register_netdev: err_register_netdev:
...@@ -4911,7 +4898,7 @@ static int rocker_probe_ports(struct rocker *rocker) ...@@ -4911,7 +4898,7 @@ static int rocker_probe_ports(struct rocker *rocker)
int err; int err;
alloc_size = sizeof(struct rocker_port *) * rocker->port_count; alloc_size = sizeof(struct rocker_port *) * rocker->port_count;
rocker->ports = kmalloc(alloc_size, GFP_KERNEL); rocker->ports = kzalloc(alloc_size, GFP_KERNEL);
if (!rocker->ports) if (!rocker->ports)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < rocker->port_count; i++) { for (i = 0; i < rocker->port_count; i++) {
...@@ -5134,41 +5121,49 @@ static bool rocker_port_dev_check(const struct net_device *dev) ...@@ -5134,41 +5121,49 @@ static bool rocker_port_dev_check(const struct net_device *dev)
static int rocker_port_bridge_join(struct rocker_port *rocker_port, static int rocker_port_bridge_join(struct rocker_port *rocker_port,
struct net_device *bridge) struct net_device *bridge)
{ {
u16 untagged_vid = 0;
int err; int err;
rocker_port_internal_vlan_id_put(rocker_port, /* Port is joining bridge, so the internal VLAN for the
rocker_port->dev->ifindex); * port is going to change to the bridge internal VLAN.
* Let's remove untagged VLAN (vid=0) from port and
rocker_port->bridge_dev = bridge; * re-add once internal VLAN has changed.
*/
/* Use bridge internal VLAN ID for untagged pkts */ err = rocker_port_vlan_del(rocker_port, untagged_vid, 0);
err = rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE,
ROCKER_OP_FLAG_REMOVE, 0);
if (err) if (err)
return err; return err;
rocker_port_internal_vlan_id_put(rocker_port,
rocker_port->dev->ifindex);
rocker_port->internal_vlan_id = rocker_port->internal_vlan_id =
rocker_port_internal_vlan_id_get(rocker_port, bridge->ifindex); rocker_port_internal_vlan_id_get(rocker_port, bridge->ifindex);
return rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, 0);
rocker_port->bridge_dev = bridge;
return rocker_port_vlan_add(rocker_port, SWITCHDEV_TRANS_NONE,
untagged_vid, 0);
} }
static int rocker_port_bridge_leave(struct rocker_port *rocker_port) static int rocker_port_bridge_leave(struct rocker_port *rocker_port)
{ {
u16 untagged_vid = 0;
int err; int err;
rocker_port_internal_vlan_id_put(rocker_port, err = rocker_port_vlan_del(rocker_port, untagged_vid, 0);
rocker_port->bridge_dev->ifindex);
rocker_port->bridge_dev = NULL;
/* Use port internal VLAN ID for untagged pkts */
err = rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE,
ROCKER_OP_FLAG_REMOVE, 0);
if (err) if (err)
return err; return err;
rocker_port_internal_vlan_id_put(rocker_port,
rocker_port->bridge_dev->ifindex);
rocker_port->internal_vlan_id = rocker_port->internal_vlan_id =
rocker_port_internal_vlan_id_get(rocker_port, rocker_port_internal_vlan_id_get(rocker_port,
rocker_port->dev->ifindex); rocker_port->dev->ifindex);
err = rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, 0);
rocker_port->bridge_dev = NULL;
err = rocker_port_vlan_add(rocker_port, SWITCHDEV_TRANS_NONE,
untagged_vid, 0);
if (err) if (err)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment