Commit 4314b1f6 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-fixes'

Daniel Borkmann says:

====================
pull-request: bpf 2019-01-08

The following pull-request contains BPF updates for your *net* tree.

The main changes are:

1) Fix BSD'ism in sendmsg(2) to rewrite unspecified IPv6 dst for
   unconnected UDP sockets with [::1] _after_ cgroup BPF invocation,
   from Andrey.

2) Follow-up fix to the speculation fix where we need to reject a
   corner case for sanitation when ptr and scalars are mixed in the
   same alu op. Also, some unrelated minor doc fixes, from Daniel.

3) Fix BPF kselftest's incorrect uses of create_and_get_cgroup()
   by not assuming fd of zero value to be the result of an error
   case, from Stanislav.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 11287b69 4fabf3bf
...@@ -78,6 +78,7 @@ config MLXSW_SPECTRUM ...@@ -78,6 +78,7 @@ config MLXSW_SPECTRUM
depends on IPV6 || IPV6=n depends on IPV6 || IPV6=n
depends on NET_IPGRE || NET_IPGRE=n depends on NET_IPGRE || NET_IPGRE=n
depends on IPV6_GRE || IPV6_GRE=n depends on IPV6_GRE || IPV6_GRE=n
depends on VXLAN || VXLAN=n
select GENERIC_ALLOCATOR select GENERIC_ALLOCATOR
select PARMAN select PARMAN
select OBJAGG select OBJAGG
......
...@@ -5005,12 +5005,15 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev, ...@@ -5005,12 +5005,15 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
lower_dev, lower_dev,
upper_dev); upper_dev);
} else if (netif_is_lag_master(upper_dev)) { } else if (netif_is_lag_master(upper_dev)) {
if (info->linking) if (info->linking) {
err = mlxsw_sp_port_lag_join(mlxsw_sp_port, err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
upper_dev); upper_dev);
else } else {
mlxsw_sp_port_lag_tx_en_set(mlxsw_sp_port,
false);
mlxsw_sp_port_lag_leave(mlxsw_sp_port, mlxsw_sp_port_lag_leave(mlxsw_sp_port,
upper_dev); upper_dev);
}
} else if (netif_is_ovs_master(upper_dev)) { } else if (netif_is_ovs_master(upper_dev)) {
if (info->linking) if (info->linking)
err = mlxsw_sp_port_ovs_join(mlxsw_sp_port); err = mlxsw_sp_port_ovs_join(mlxsw_sp_port);
......
...@@ -72,7 +72,15 @@ mlxsw_sp_acl_ctcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, ...@@ -72,7 +72,15 @@ mlxsw_sp_acl_ctcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp,
act_set = mlxsw_afa_block_first_set(rulei->act_block); act_set = mlxsw_afa_block_first_set(rulei->act_block);
mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set); mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl);
if (err)
goto err_ptce2_write;
return 0;
err_ptce2_write:
cregion->ops->entry_remove(cregion, centry);
return err;
} }
static void static void
......
...@@ -1022,7 +1022,6 @@ void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion, ...@@ -1022,7 +1022,6 @@ void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
{ {
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask; struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
ASSERT_RTNL();
objagg_obj_put(aregion->erp_table->objagg, objagg_obj); objagg_obj_put(aregion->erp_table->objagg, objagg_obj);
} }
...@@ -1054,7 +1053,6 @@ void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp, ...@@ -1054,7 +1053,6 @@ void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_acl_erp *erp = objagg_obj_root_priv(objagg_obj); const struct mlxsw_sp_acl_erp *erp = objagg_obj_root_priv(objagg_obj);
unsigned int erp_bank; unsigned int erp_bank;
ASSERT_RTNL();
if (!mlxsw_sp_acl_erp_table_is_used(erp->erp_table)) if (!mlxsw_sp_acl_erp_table_is_used(erp->erp_table))
return; return;
......
...@@ -816,14 +816,14 @@ int mlxsw_sp_nve_fid_enable(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *fid, ...@@ -816,14 +816,14 @@ int mlxsw_sp_nve_fid_enable(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *fid,
ops = nve->nve_ops_arr[params->type]; ops = nve->nve_ops_arr[params->type];
if (!ops->can_offload(nve, params->dev, extack)) if (!ops->can_offload(nve, params->dev, extack))
return -EOPNOTSUPP; return -EINVAL;
memset(&config, 0, sizeof(config)); memset(&config, 0, sizeof(config));
ops->nve_config(nve, params->dev, &config); ops->nve_config(nve, params->dev, &config);
if (nve->num_nve_tunnels && if (nve->num_nve_tunnels &&
memcmp(&config, &nve->config, sizeof(config))) { memcmp(&config, &nve->config, sizeof(config))) {
NL_SET_ERR_MSG_MOD(extack, "Conflicting NVE tunnels configuration"); NL_SET_ERR_MSG_MOD(extack, "Conflicting NVE tunnels configuration");
return -EOPNOTSUPP; return -EINVAL;
} }
err = mlxsw_sp_nve_tunnel_init(mlxsw_sp, &config); err = mlxsw_sp_nve_tunnel_init(mlxsw_sp, &config);
......
...@@ -1078,8 +1078,7 @@ static int ...@@ -1078,8 +1078,7 @@ static int
mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port, mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_bridge_port *bridge_port, struct mlxsw_sp_bridge_port *bridge_port,
u16 vid, bool is_untagged, bool is_pvid, u16 vid, bool is_untagged, bool is_pvid,
struct netlink_ext_ack *extack, struct netlink_ext_ack *extack)
struct switchdev_trans *trans)
{ {
u16 pvid = mlxsw_sp_port_pvid_determine(mlxsw_sp_port, vid, is_pvid); u16 pvid = mlxsw_sp_port_pvid_determine(mlxsw_sp_port, vid, is_pvid);
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
...@@ -1095,9 +1094,6 @@ mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1095,9 +1094,6 @@ mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
mlxsw_sp_port_vlan->bridge_port != bridge_port) mlxsw_sp_port_vlan->bridge_port != bridge_port)
return -EEXIST; return -EEXIST;
if (switchdev_trans_ph_prepare(trans))
return 0;
if (!mlxsw_sp_port_vlan) { if (!mlxsw_sp_port_vlan) {
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_create(mlxsw_sp_port, mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_create(mlxsw_sp_port,
vid); vid);
...@@ -1188,6 +1184,9 @@ static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1188,6 +1184,9 @@ static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
return err; return err;
} }
if (switchdev_trans_ph_commit(trans))
return 0;
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev); bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
if (WARN_ON(!bridge_port)) if (WARN_ON(!bridge_port))
return -EINVAL; return -EINVAL;
...@@ -1200,7 +1199,7 @@ static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1200,7 +1199,7 @@ static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
err = mlxsw_sp_bridge_port_vlan_add(mlxsw_sp_port, bridge_port, err = mlxsw_sp_bridge_port_vlan_add(mlxsw_sp_port, bridge_port,
vid, flag_untagged, vid, flag_untagged,
flag_pvid, extack, trans); flag_pvid, extack);
if (err) if (err)
return err; return err;
} }
...@@ -1808,7 +1807,7 @@ static void ...@@ -1808,7 +1807,7 @@ static void
mlxsw_sp_bridge_port_vlan_del(struct mlxsw_sp_port *mlxsw_sp_port, mlxsw_sp_bridge_port_vlan_del(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_bridge_port *bridge_port, u16 vid) struct mlxsw_sp_bridge_port *bridge_port, u16 vid)
{ {
u16 pvid = mlxsw_sp_port->pvid == vid ? 0 : vid; u16 pvid = mlxsw_sp_port->pvid == vid ? 0 : mlxsw_sp_port->pvid;
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid); mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
...@@ -3207,7 +3206,6 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp, ...@@ -3207,7 +3206,6 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_bridge_device *bridge_device, struct mlxsw_sp_bridge_device *bridge_device,
const struct net_device *vxlan_dev, u16 vid, const struct net_device *vxlan_dev, u16 vid,
bool flag_untagged, bool flag_pvid, bool flag_untagged, bool flag_pvid,
struct switchdev_trans *trans,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct vxlan_dev *vxlan = netdev_priv(vxlan_dev); struct vxlan_dev *vxlan = netdev_priv(vxlan_dev);
...@@ -3225,9 +3223,6 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp, ...@@ -3225,9 +3223,6 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_bridge_8021q_vxlan_dev_find(bridge_device->dev, vid)) mlxsw_sp_bridge_8021q_vxlan_dev_find(bridge_device->dev, vid))
return -EINVAL; return -EINVAL;
if (switchdev_trans_ph_prepare(trans))
return 0;
if (!netif_running(vxlan_dev)) if (!netif_running(vxlan_dev))
return 0; return 0;
...@@ -3345,6 +3340,9 @@ mlxsw_sp_switchdev_vxlan_vlans_add(struct net_device *vxlan_dev, ...@@ -3345,6 +3340,9 @@ mlxsw_sp_switchdev_vxlan_vlans_add(struct net_device *vxlan_dev,
port_obj_info->handled = true; port_obj_info->handled = true;
if (switchdev_trans_ph_commit(trans))
return 0;
bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev); bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
if (!bridge_device) if (!bridge_device)
return -EINVAL; return -EINVAL;
...@@ -3358,8 +3356,7 @@ mlxsw_sp_switchdev_vxlan_vlans_add(struct net_device *vxlan_dev, ...@@ -3358,8 +3356,7 @@ mlxsw_sp_switchdev_vxlan_vlans_add(struct net_device *vxlan_dev,
err = mlxsw_sp_switchdev_vxlan_vlan_add(mlxsw_sp, bridge_device, err = mlxsw_sp_switchdev_vxlan_vlan_add(mlxsw_sp, bridge_device,
vxlan_dev, vid, vxlan_dev, vid,
flag_untagged, flag_untagged,
flag_pvid, trans, flag_pvid, extack);
extack);
if (err) if (err)
return err; return err;
} }
......
...@@ -107,6 +107,7 @@ struct br_tunnel_info { ...@@ -107,6 +107,7 @@ struct br_tunnel_info {
/* private vlan flags */ /* private vlan flags */
enum { enum {
BR_VLFLAG_PER_PORT_STATS = BIT(0), BR_VLFLAG_PER_PORT_STATS = BIT(0),
BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1),
}; };
/** /**
......
...@@ -80,16 +80,18 @@ static bool __vlan_add_flags(struct net_bridge_vlan *v, u16 flags) ...@@ -80,16 +80,18 @@ static bool __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
} }
static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
u16 vid, u16 flags, struct netlink_ext_ack *extack) struct net_bridge_vlan *v, u16 flags,
struct netlink_ext_ack *extack)
{ {
int err; int err;
/* Try switchdev op first. In case it is not supported, fallback to /* Try switchdev op first. In case it is not supported, fallback to
* 8021q add. * 8021q add.
*/ */
err = br_switchdev_port_vlan_add(dev, vid, flags, extack); err = br_switchdev_port_vlan_add(dev, v->vid, flags, extack);
if (err == -EOPNOTSUPP) if (err == -EOPNOTSUPP)
return vlan_vid_add(dev, br->vlan_proto, vid); return vlan_vid_add(dev, br->vlan_proto, v->vid);
v->priv_flags |= BR_VLFLAG_ADDED_BY_SWITCHDEV;
return err; return err;
} }
...@@ -121,19 +123,17 @@ static void __vlan_del_list(struct net_bridge_vlan *v) ...@@ -121,19 +123,17 @@ static void __vlan_del_list(struct net_bridge_vlan *v)
} }
static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br, static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,
u16 vid) const struct net_bridge_vlan *v)
{ {
int err; int err;
/* Try switchdev op first. In case it is not supported, fallback to /* Try switchdev op first. In case it is not supported, fallback to
* 8021q del. * 8021q del.
*/ */
err = br_switchdev_port_vlan_del(dev, vid); err = br_switchdev_port_vlan_del(dev, v->vid);
if (err == -EOPNOTSUPP) { if (!(v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV))
vlan_vid_del(dev, br->vlan_proto, vid); vlan_vid_del(dev, br->vlan_proto, v->vid);
return 0; return err == -EOPNOTSUPP ? 0 : err;
}
return err;
} }
/* Returns a master vlan, if it didn't exist it gets created. In all cases a /* Returns a master vlan, if it didn't exist it gets created. In all cases a
...@@ -242,7 +242,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, ...@@ -242,7 +242,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
* This ensures tagged traffic enters the bridge when * This ensures tagged traffic enters the bridge when
* promiscuous mode is disabled by br_manage_promisc(). * promiscuous mode is disabled by br_manage_promisc().
*/ */
err = __vlan_vid_add(dev, br, v->vid, flags, extack); err = __vlan_vid_add(dev, br, v, flags, extack);
if (err) if (err)
goto out; goto out;
...@@ -305,7 +305,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, ...@@ -305,7 +305,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
out_filt: out_filt:
if (p) { if (p) {
__vlan_vid_del(dev, br, v->vid); __vlan_vid_del(dev, br, v);
if (masterv) { if (masterv) {
if (v->stats && masterv->stats != v->stats) if (v->stats && masterv->stats != v->stats)
free_percpu(v->stats); free_percpu(v->stats);
...@@ -338,7 +338,7 @@ static int __vlan_del(struct net_bridge_vlan *v) ...@@ -338,7 +338,7 @@ static int __vlan_del(struct net_bridge_vlan *v)
__vlan_delete_pvid(vg, v->vid); __vlan_delete_pvid(vg, v->vid);
if (p) { if (p) {
err = __vlan_vid_del(p->dev, p->br, v->vid); err = __vlan_vid_del(p->dev, p->br, v);
if (err) if (err)
goto out; goto out;
} else { } else {
......
...@@ -847,6 +847,24 @@ sanitization_vlan_aware_test() ...@@ -847,6 +847,24 @@ sanitization_vlan_aware_test()
log_test "vlan-aware - failed enslavement to vlan-aware bridge" log_test "vlan-aware - failed enslavement to vlan-aware bridge"
bridge vlan del vid 10 dev vxlan20
bridge vlan add vid 20 dev vxlan20 pvid untagged
# Test that offloading of an unsupported tunnel fails when it is
# triggered by addition of VLAN to a local port
RET=0
# TOS must be set to inherit
ip link set dev vxlan10 type vxlan tos 42
ip link set dev $swp1 master br0
bridge vlan add vid 10 dev $swp1 &> /dev/null
check_fail $?
log_test "vlan-aware - failed vlan addition to a local port"
ip link set dev vxlan10 type vxlan tos inherit
ip link del dev vxlan20 ip link del dev vxlan20
ip link del dev vxlan10 ip link del dev vxlan10
ip link del dev br0 ip link del dev br0
......
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
ALL_TESTS="ping_ipv4 ping_ipv6 learning flooding" ALL_TESTS="ping_ipv4 ping_ipv6 learning flooding vlan_deletion"
NUM_NETIFS=4 NUM_NETIFS=4
CHECK_TC="yes" CHECK_TC="yes"
source lib.sh source lib.sh
...@@ -96,6 +96,19 @@ flooding() ...@@ -96,6 +96,19 @@ flooding()
flood_test $swp2 $h1 $h2 flood_test $swp2 $h1 $h2
} }
vlan_deletion()
{
# Test that the deletion of a VLAN on a bridge port does not affect
# the PVID VLAN
log_info "Add and delete a VLAN on bridge port $swp1"
bridge vlan add vid 10 dev $swp1
bridge vlan del vid 10 dev $swp1
ping_ipv4
ping_ipv6
}
trap cleanup EXIT trap cleanup EXIT
setup_prepare setup_prepare
......
...@@ -629,7 +629,7 @@ __test_ecn_decap() ...@@ -629,7 +629,7 @@ __test_ecn_decap()
RET=0 RET=0
tc filter add dev $h1 ingress pref 77 prot ip \ tc filter add dev $h1 ingress pref 77 prot ip \
flower ip_tos $decapped_tos action pass flower ip_tos $decapped_tos action drop
sleep 1 sleep 1
vxlan_encapped_ping_test v2 v1 192.0.2.17 \ vxlan_encapped_ping_test v2 v1 192.0.2.17 \
$orig_inner_tos $orig_outer_tos \ $orig_inner_tos $orig_outer_tos \
......
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