1 /* 2 * drivers/net/ethernet/mellanox/mlxsw/mlxsw_span.c 3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2018 Petr Machata <petrm@mellanox.com> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the names of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * Alternatively, this software may be distributed under the terms of the 19 * GNU General Public License ("GPL") version 2 as published by the Free 20 * Software Foundation. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <linux/if_bridge.h> 36 #include <linux/list.h> 37 #include <net/arp.h> 38 #include <net/gre.h> 39 #include <net/ndisc.h> 40 #include <net/ip6_tunnel.h> 41 42 #include "spectrum.h" 43 #include "spectrum_ipip.h" 44 #include "spectrum_span.h" 45 #include "spectrum_switchdev.h" 46 47 int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp) 48 { 49 int i; 50 51 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN)) 52 return -EIO; 53 54 mlxsw_sp->span.entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, 55 MAX_SPAN); 56 mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count, 57 sizeof(struct mlxsw_sp_span_entry), 58 GFP_KERNEL); 59 if (!mlxsw_sp->span.entries) 60 return -ENOMEM; 61 62 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 63 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i]; 64 65 INIT_LIST_HEAD(&curr->bound_ports_list); 66 curr->id = i; 67 } 68 69 return 0; 70 } 71 72 void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp) 73 { 74 int i; 75 76 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 77 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i]; 78 79 WARN_ON_ONCE(!list_empty(&curr->bound_ports_list)); 80 } 81 kfree(mlxsw_sp->span.entries); 82 } 83 84 static int 85 mlxsw_sp_span_entry_phys_parms(const struct net_device *to_dev, 86 struct mlxsw_sp_span_parms *sparmsp) 87 { 88 sparmsp->dest_port = netdev_priv(to_dev); 89 return 0; 90 } 91 92 static int 93 mlxsw_sp_span_entry_phys_configure(struct mlxsw_sp_span_entry *span_entry, 94 struct mlxsw_sp_span_parms sparms) 95 { 96 struct mlxsw_sp_port *dest_port = sparms.dest_port; 97 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp; 98 u8 local_port = dest_port->local_port; 99 char mpat_pl[MLXSW_REG_MPAT_LEN]; 100 int pa_id = span_entry->id; 101 102 /* Create a new port analayzer entry for local_port. */ 103 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true, 104 MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH); 105 106 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl); 107 } 108 109 static void 110 mlxsw_sp_span_entry_deconfigure_common(struct mlxsw_sp_span_entry *span_entry, 111 enum mlxsw_reg_mpat_span_type span_type) 112 { 113 struct mlxsw_sp_port *dest_port = span_entry->parms.dest_port; 114 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp; 115 u8 local_port = dest_port->local_port; 116 char mpat_pl[MLXSW_REG_MPAT_LEN]; 117 int pa_id = span_entry->id; 118 119 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, false, span_type); 120 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl); 121 } 122 123 static void 124 mlxsw_sp_span_entry_phys_deconfigure(struct mlxsw_sp_span_entry *span_entry) 125 { 126 mlxsw_sp_span_entry_deconfigure_common(span_entry, 127 MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH); 128 } 129 130 static const 131 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = { 132 .can_handle = mlxsw_sp_port_dev_check, 133 .parms = mlxsw_sp_span_entry_phys_parms, 134 .configure = mlxsw_sp_span_entry_phys_configure, 135 .deconfigure = mlxsw_sp_span_entry_phys_deconfigure, 136 }; 137 138 static int mlxsw_sp_span_dmac(struct neigh_table *tbl, 139 const void *pkey, 140 struct net_device *dev, 141 unsigned char dmac[ETH_ALEN]) 142 { 143 struct neighbour *neigh = neigh_lookup(tbl, pkey, dev); 144 int err = 0; 145 146 if (!neigh) { 147 neigh = neigh_create(tbl, pkey, dev); 148 if (IS_ERR(neigh)) 149 return PTR_ERR(neigh); 150 } 151 152 neigh_event_send(neigh, NULL); 153 154 read_lock_bh(&neigh->lock); 155 if ((neigh->nud_state & NUD_VALID) && !neigh->dead) 156 memcpy(dmac, neigh->ha, ETH_ALEN); 157 else 158 err = -ENOENT; 159 read_unlock_bh(&neigh->lock); 160 161 neigh_release(neigh); 162 return err; 163 } 164 165 static int 166 mlxsw_sp_span_entry_unoffloadable(struct mlxsw_sp_span_parms *sparmsp) 167 { 168 sparmsp->dest_port = NULL; 169 return 0; 170 } 171 172 static struct net_device * 173 mlxsw_sp_span_entry_bridge_8021q(const struct net_device *br_dev, 174 unsigned char *dmac, 175 u16 *p_vid) 176 { 177 struct bridge_vlan_info vinfo; 178 struct net_device *edev; 179 u16 vid = *p_vid; 180 181 if (!vid && WARN_ON(br_vlan_get_pvid(br_dev, &vid))) 182 return NULL; 183 if (!vid || 184 br_vlan_get_info(br_dev, vid, &vinfo) || 185 !(vinfo.flags & BRIDGE_VLAN_INFO_BRENTRY)) 186 return NULL; 187 188 edev = br_fdb_find_port(br_dev, dmac, vid); 189 if (!edev) 190 return NULL; 191 192 if (br_vlan_get_info(edev, vid, &vinfo)) 193 return NULL; 194 if (vinfo.flags & BRIDGE_VLAN_INFO_UNTAGGED) 195 *p_vid = 0; 196 else 197 *p_vid = vid; 198 return edev; 199 } 200 201 static struct net_device * 202 mlxsw_sp_span_entry_bridge_8021d(const struct net_device *br_dev, 203 unsigned char *dmac) 204 { 205 return br_fdb_find_port(br_dev, dmac, 0); 206 } 207 208 static struct net_device * 209 mlxsw_sp_span_entry_bridge(const struct net_device *br_dev, 210 unsigned char dmac[ETH_ALEN], 211 u16 *p_vid) 212 { 213 struct mlxsw_sp_bridge_port *bridge_port; 214 enum mlxsw_reg_spms_state spms_state; 215 struct net_device *dev = NULL; 216 struct mlxsw_sp_port *port; 217 u8 stp_state; 218 219 if (br_vlan_enabled(br_dev)) 220 dev = mlxsw_sp_span_entry_bridge_8021q(br_dev, dmac, p_vid); 221 else if (!*p_vid) 222 dev = mlxsw_sp_span_entry_bridge_8021d(br_dev, dmac); 223 if (!dev) 224 return NULL; 225 226 port = mlxsw_sp_port_dev_lower_find(dev); 227 if (!port) 228 return NULL; 229 230 bridge_port = mlxsw_sp_bridge_port_find(port->mlxsw_sp->bridge, dev); 231 if (!bridge_port) 232 return NULL; 233 234 stp_state = mlxsw_sp_bridge_port_stp_state(bridge_port); 235 spms_state = mlxsw_sp_stp_spms_state(stp_state); 236 if (spms_state != MLXSW_REG_SPMS_STATE_FORWARDING) 237 return NULL; 238 239 return dev; 240 } 241 242 static struct net_device * 243 mlxsw_sp_span_entry_vlan(const struct net_device *vlan_dev, 244 u16 *p_vid) 245 { 246 *p_vid = vlan_dev_vlan_id(vlan_dev); 247 return vlan_dev_real_dev(vlan_dev); 248 } 249 250 static struct net_device * 251 mlxsw_sp_span_entry_lag(struct net_device *lag_dev) 252 { 253 struct net_device *dev; 254 struct list_head *iter; 255 256 netdev_for_each_lower_dev(lag_dev, dev, iter) 257 if ((dev->flags & IFF_UP) && mlxsw_sp_port_dev_check(dev)) 258 return dev; 259 260 return NULL; 261 } 262 263 static __maybe_unused int 264 mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *edev, 265 union mlxsw_sp_l3addr saddr, 266 union mlxsw_sp_l3addr daddr, 267 union mlxsw_sp_l3addr gw, 268 __u8 ttl, 269 struct neigh_table *tbl, 270 struct mlxsw_sp_span_parms *sparmsp) 271 { 272 unsigned char dmac[ETH_ALEN]; 273 u16 vid = 0; 274 275 if (mlxsw_sp_l3addr_is_zero(gw)) 276 gw = daddr; 277 278 if (!edev || mlxsw_sp_span_dmac(tbl, &gw, edev, dmac)) 279 goto unoffloadable; 280 281 if (is_vlan_dev(edev)) 282 edev = mlxsw_sp_span_entry_vlan(edev, &vid); 283 284 if (netif_is_bridge_master(edev)) { 285 edev = mlxsw_sp_span_entry_bridge(edev, dmac, &vid); 286 if (!edev) 287 goto unoffloadable; 288 } 289 290 if (is_vlan_dev(edev)) { 291 if (vid || !(edev->flags & IFF_UP)) 292 goto unoffloadable; 293 edev = mlxsw_sp_span_entry_vlan(edev, &vid); 294 } 295 296 if (netif_is_lag_master(edev)) { 297 if (!(edev->flags & IFF_UP)) 298 goto unoffloadable; 299 edev = mlxsw_sp_span_entry_lag(edev); 300 if (!edev) 301 goto unoffloadable; 302 } 303 304 if (!mlxsw_sp_port_dev_check(edev)) 305 goto unoffloadable; 306 307 sparmsp->dest_port = netdev_priv(edev); 308 sparmsp->ttl = ttl; 309 memcpy(sparmsp->dmac, dmac, ETH_ALEN); 310 memcpy(sparmsp->smac, edev->dev_addr, ETH_ALEN); 311 sparmsp->saddr = saddr; 312 sparmsp->daddr = daddr; 313 sparmsp->vid = vid; 314 return 0; 315 316 unoffloadable: 317 return mlxsw_sp_span_entry_unoffloadable(sparmsp); 318 } 319 320 #if IS_ENABLED(CONFIG_NET_IPGRE) 321 static struct net_device * 322 mlxsw_sp_span_gretap4_route(const struct net_device *to_dev, 323 __be32 *saddrp, __be32 *daddrp) 324 { 325 struct ip_tunnel *tun = netdev_priv(to_dev); 326 struct net_device *dev = NULL; 327 struct ip_tunnel_parm parms; 328 struct rtable *rt = NULL; 329 struct flowi4 fl4; 330 331 /* We assume "dev" stays valid after rt is put. */ 332 ASSERT_RTNL(); 333 334 parms = mlxsw_sp_ipip_netdev_parms4(to_dev); 335 ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, 336 0, 0, parms.link, tun->fwmark); 337 338 rt = ip_route_output_key(tun->net, &fl4); 339 if (IS_ERR(rt)) 340 return NULL; 341 342 if (rt->rt_type != RTN_UNICAST) 343 goto out; 344 345 dev = rt->dst.dev; 346 *saddrp = fl4.saddr; 347 *daddrp = rt->rt_gateway; 348 349 out: 350 ip_rt_put(rt); 351 return dev; 352 } 353 354 static int 355 mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev, 356 struct mlxsw_sp_span_parms *sparmsp) 357 { 358 struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev); 359 union mlxsw_sp_l3addr saddr = { .addr4 = tparm.iph.saddr }; 360 union mlxsw_sp_l3addr daddr = { .addr4 = tparm.iph.daddr }; 361 bool inherit_tos = tparm.iph.tos & 0x1; 362 bool inherit_ttl = !tparm.iph.ttl; 363 union mlxsw_sp_l3addr gw = daddr; 364 struct net_device *l3edev; 365 366 if (!(to_dev->flags & IFF_UP) || 367 /* Reject tunnels with GRE keys, checksums, etc. */ 368 tparm.i_flags || tparm.o_flags || 369 /* Require a fixed TTL and a TOS copied from the mirrored packet. */ 370 inherit_ttl || !inherit_tos || 371 /* A destination address may not be "any". */ 372 mlxsw_sp_l3addr_is_zero(daddr)) 373 return mlxsw_sp_span_entry_unoffloadable(sparmsp); 374 375 l3edev = mlxsw_sp_span_gretap4_route(to_dev, &saddr.addr4, &gw.addr4); 376 return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw, 377 tparm.iph.ttl, 378 &arp_tbl, sparmsp); 379 } 380 381 static int 382 mlxsw_sp_span_entry_gretap4_configure(struct mlxsw_sp_span_entry *span_entry, 383 struct mlxsw_sp_span_parms sparms) 384 { 385 struct mlxsw_sp_port *dest_port = sparms.dest_port; 386 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp; 387 u8 local_port = dest_port->local_port; 388 char mpat_pl[MLXSW_REG_MPAT_LEN]; 389 int pa_id = span_entry->id; 390 391 /* Create a new port analayzer entry for local_port. */ 392 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true, 393 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3); 394 mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid); 395 mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl, 396 MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER, 397 sparms.dmac, !!sparms.vid); 398 mlxsw_reg_mpat_eth_rspan_l3_ipv4_pack(mpat_pl, 399 sparms.ttl, sparms.smac, 400 be32_to_cpu(sparms.saddr.addr4), 401 be32_to_cpu(sparms.daddr.addr4)); 402 403 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl); 404 } 405 406 static void 407 mlxsw_sp_span_entry_gretap4_deconfigure(struct mlxsw_sp_span_entry *span_entry) 408 { 409 mlxsw_sp_span_entry_deconfigure_common(span_entry, 410 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3); 411 } 412 413 static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap4 = { 414 .can_handle = is_gretap_dev, 415 .parms = mlxsw_sp_span_entry_gretap4_parms, 416 .configure = mlxsw_sp_span_entry_gretap4_configure, 417 .deconfigure = mlxsw_sp_span_entry_gretap4_deconfigure, 418 }; 419 #endif 420 421 #if IS_ENABLED(CONFIG_IPV6_GRE) 422 static struct net_device * 423 mlxsw_sp_span_gretap6_route(const struct net_device *to_dev, 424 struct in6_addr *saddrp, 425 struct in6_addr *daddrp) 426 { 427 struct ip6_tnl *t = netdev_priv(to_dev); 428 struct flowi6 fl6 = t->fl.u.ip6; 429 struct net_device *dev = NULL; 430 struct dst_entry *dst; 431 struct rt6_info *rt6; 432 433 /* We assume "dev" stays valid after dst is released. */ 434 ASSERT_RTNL(); 435 436 fl6.flowi6_mark = t->parms.fwmark; 437 if (!ip6_tnl_xmit_ctl(t, &fl6.saddr, &fl6.daddr)) 438 return NULL; 439 440 dst = ip6_route_output(t->net, NULL, &fl6); 441 if (!dst || dst->error) 442 goto out; 443 444 rt6 = container_of(dst, struct rt6_info, dst); 445 446 dev = dst->dev; 447 *saddrp = fl6.saddr; 448 *daddrp = rt6->rt6i_gateway; 449 450 out: 451 dst_release(dst); 452 return dev; 453 } 454 455 static int 456 mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev, 457 struct mlxsw_sp_span_parms *sparmsp) 458 { 459 struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(to_dev); 460 bool inherit_tos = tparm.flags & IP6_TNL_F_USE_ORIG_TCLASS; 461 union mlxsw_sp_l3addr saddr = { .addr6 = tparm.laddr }; 462 union mlxsw_sp_l3addr daddr = { .addr6 = tparm.raddr }; 463 bool inherit_ttl = !tparm.hop_limit; 464 union mlxsw_sp_l3addr gw = daddr; 465 struct net_device *l3edev; 466 467 if (!(to_dev->flags & IFF_UP) || 468 /* Reject tunnels with GRE keys, checksums, etc. */ 469 tparm.i_flags || tparm.o_flags || 470 /* Require a fixed TTL and a TOS copied from the mirrored packet. */ 471 inherit_ttl || !inherit_tos || 472 /* A destination address may not be "any". */ 473 mlxsw_sp_l3addr_is_zero(daddr)) 474 return mlxsw_sp_span_entry_unoffloadable(sparmsp); 475 476 l3edev = mlxsw_sp_span_gretap6_route(to_dev, &saddr.addr6, &gw.addr6); 477 return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw, 478 tparm.hop_limit, 479 &nd_tbl, sparmsp); 480 } 481 482 static int 483 mlxsw_sp_span_entry_gretap6_configure(struct mlxsw_sp_span_entry *span_entry, 484 struct mlxsw_sp_span_parms sparms) 485 { 486 struct mlxsw_sp_port *dest_port = sparms.dest_port; 487 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp; 488 u8 local_port = dest_port->local_port; 489 char mpat_pl[MLXSW_REG_MPAT_LEN]; 490 int pa_id = span_entry->id; 491 492 /* Create a new port analayzer entry for local_port. */ 493 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true, 494 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3); 495 mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid); 496 mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl, 497 MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER, 498 sparms.dmac, !!sparms.vid); 499 mlxsw_reg_mpat_eth_rspan_l3_ipv6_pack(mpat_pl, sparms.ttl, sparms.smac, 500 sparms.saddr.addr6, 501 sparms.daddr.addr6); 502 503 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl); 504 } 505 506 static void 507 mlxsw_sp_span_entry_gretap6_deconfigure(struct mlxsw_sp_span_entry *span_entry) 508 { 509 mlxsw_sp_span_entry_deconfigure_common(span_entry, 510 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3); 511 } 512 513 static const 514 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap6 = { 515 .can_handle = is_ip6gretap_dev, 516 .parms = mlxsw_sp_span_entry_gretap6_parms, 517 .configure = mlxsw_sp_span_entry_gretap6_configure, 518 .deconfigure = mlxsw_sp_span_entry_gretap6_deconfigure, 519 }; 520 #endif 521 522 static bool 523 mlxsw_sp_span_vlan_can_handle(const struct net_device *dev) 524 { 525 return is_vlan_dev(dev) && 526 mlxsw_sp_port_dev_check(vlan_dev_real_dev(dev)); 527 } 528 529 static int 530 mlxsw_sp_span_entry_vlan_parms(const struct net_device *to_dev, 531 struct mlxsw_sp_span_parms *sparmsp) 532 { 533 struct net_device *real_dev; 534 u16 vid; 535 536 if (!(to_dev->flags & IFF_UP)) 537 return mlxsw_sp_span_entry_unoffloadable(sparmsp); 538 539 real_dev = mlxsw_sp_span_entry_vlan(to_dev, &vid); 540 sparmsp->dest_port = netdev_priv(real_dev); 541 sparmsp->vid = vid; 542 return 0; 543 } 544 545 static int 546 mlxsw_sp_span_entry_vlan_configure(struct mlxsw_sp_span_entry *span_entry, 547 struct mlxsw_sp_span_parms sparms) 548 { 549 struct mlxsw_sp_port *dest_port = sparms.dest_port; 550 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp; 551 u8 local_port = dest_port->local_port; 552 char mpat_pl[MLXSW_REG_MPAT_LEN]; 553 int pa_id = span_entry->id; 554 555 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true, 556 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH); 557 mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid); 558 559 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl); 560 } 561 562 static void 563 mlxsw_sp_span_entry_vlan_deconfigure(struct mlxsw_sp_span_entry *span_entry) 564 { 565 mlxsw_sp_span_entry_deconfigure_common(span_entry, 566 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH); 567 } 568 569 static const 570 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_vlan = { 571 .can_handle = mlxsw_sp_span_vlan_can_handle, 572 .parms = mlxsw_sp_span_entry_vlan_parms, 573 .configure = mlxsw_sp_span_entry_vlan_configure, 574 .deconfigure = mlxsw_sp_span_entry_vlan_deconfigure, 575 }; 576 577 static const 578 struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = { 579 &mlxsw_sp_span_entry_ops_phys, 580 #if IS_ENABLED(CONFIG_NET_IPGRE) 581 &mlxsw_sp_span_entry_ops_gretap4, 582 #endif 583 #if IS_ENABLED(CONFIG_IPV6_GRE) 584 &mlxsw_sp_span_entry_ops_gretap6, 585 #endif 586 &mlxsw_sp_span_entry_ops_vlan, 587 }; 588 589 static int 590 mlxsw_sp_span_entry_nop_parms(const struct net_device *to_dev, 591 struct mlxsw_sp_span_parms *sparmsp) 592 { 593 return mlxsw_sp_span_entry_unoffloadable(sparmsp); 594 } 595 596 static int 597 mlxsw_sp_span_entry_nop_configure(struct mlxsw_sp_span_entry *span_entry, 598 struct mlxsw_sp_span_parms sparms) 599 { 600 return 0; 601 } 602 603 static void 604 mlxsw_sp_span_entry_nop_deconfigure(struct mlxsw_sp_span_entry *span_entry) 605 { 606 } 607 608 static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_nop = { 609 .parms = mlxsw_sp_span_entry_nop_parms, 610 .configure = mlxsw_sp_span_entry_nop_configure, 611 .deconfigure = mlxsw_sp_span_entry_nop_deconfigure, 612 }; 613 614 static void 615 mlxsw_sp_span_entry_configure(struct mlxsw_sp *mlxsw_sp, 616 struct mlxsw_sp_span_entry *span_entry, 617 struct mlxsw_sp_span_parms sparms) 618 { 619 if (sparms.dest_port) { 620 if (sparms.dest_port->mlxsw_sp != mlxsw_sp) { 621 netdev_err(span_entry->to_dev, "Cannot mirror to %s, which belongs to a different mlxsw instance", 622 sparms.dest_port->dev->name); 623 sparms.dest_port = NULL; 624 } else if (span_entry->ops->configure(span_entry, sparms)) { 625 netdev_err(span_entry->to_dev, "Failed to offload mirror to %s", 626 sparms.dest_port->dev->name); 627 sparms.dest_port = NULL; 628 } 629 } 630 631 span_entry->parms = sparms; 632 } 633 634 static void 635 mlxsw_sp_span_entry_deconfigure(struct mlxsw_sp_span_entry *span_entry) 636 { 637 if (span_entry->parms.dest_port) 638 span_entry->ops->deconfigure(span_entry); 639 } 640 641 static struct mlxsw_sp_span_entry * 642 mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp, 643 const struct net_device *to_dev, 644 const struct mlxsw_sp_span_entry_ops *ops, 645 struct mlxsw_sp_span_parms sparms) 646 { 647 struct mlxsw_sp_span_entry *span_entry = NULL; 648 int i; 649 650 /* find a free entry to use */ 651 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 652 if (!mlxsw_sp->span.entries[i].ref_count) { 653 span_entry = &mlxsw_sp->span.entries[i]; 654 break; 655 } 656 } 657 if (!span_entry) 658 return NULL; 659 660 span_entry->ops = ops; 661 span_entry->ref_count = 1; 662 span_entry->to_dev = to_dev; 663 mlxsw_sp_span_entry_configure(mlxsw_sp, span_entry, sparms); 664 665 return span_entry; 666 } 667 668 static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp_span_entry *span_entry) 669 { 670 mlxsw_sp_span_entry_deconfigure(span_entry); 671 } 672 673 struct mlxsw_sp_span_entry * 674 mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp, 675 const struct net_device *to_dev) 676 { 677 int i; 678 679 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 680 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i]; 681 682 if (curr->ref_count && curr->to_dev == to_dev) 683 return curr; 684 } 685 return NULL; 686 } 687 688 void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp, 689 struct mlxsw_sp_span_entry *span_entry) 690 { 691 mlxsw_sp_span_entry_deconfigure(span_entry); 692 span_entry->ops = &mlxsw_sp_span_entry_ops_nop; 693 } 694 695 static struct mlxsw_sp_span_entry * 696 mlxsw_sp_span_entry_find_by_id(struct mlxsw_sp *mlxsw_sp, int span_id) 697 { 698 int i; 699 700 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 701 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i]; 702 703 if (curr->ref_count && curr->id == span_id) 704 return curr; 705 } 706 return NULL; 707 } 708 709 static struct mlxsw_sp_span_entry * 710 mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp, 711 const struct net_device *to_dev, 712 const struct mlxsw_sp_span_entry_ops *ops, 713 struct mlxsw_sp_span_parms sparms) 714 { 715 struct mlxsw_sp_span_entry *span_entry; 716 717 span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, to_dev); 718 if (span_entry) { 719 /* Already exists, just take a reference */ 720 span_entry->ref_count++; 721 return span_entry; 722 } 723 724 return mlxsw_sp_span_entry_create(mlxsw_sp, to_dev, ops, sparms); 725 } 726 727 static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp, 728 struct mlxsw_sp_span_entry *span_entry) 729 { 730 WARN_ON(!span_entry->ref_count); 731 if (--span_entry->ref_count == 0) 732 mlxsw_sp_span_entry_destroy(span_entry); 733 return 0; 734 } 735 736 static bool mlxsw_sp_span_is_egress_mirror(struct mlxsw_sp_port *port) 737 { 738 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; 739 struct mlxsw_sp_span_inspected_port *p; 740 int i; 741 742 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 743 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i]; 744 745 list_for_each_entry(p, &curr->bound_ports_list, list) 746 if (p->local_port == port->local_port && 747 p->type == MLXSW_SP_SPAN_EGRESS) 748 return true; 749 } 750 751 return false; 752 } 753 754 static int mlxsw_sp_span_mtu_to_buffsize(const struct mlxsw_sp *mlxsw_sp, 755 int mtu) 756 { 757 return mlxsw_sp_bytes_cells(mlxsw_sp, mtu * 5 / 2) + 1; 758 } 759 760 int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu) 761 { 762 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; 763 char sbib_pl[MLXSW_REG_SBIB_LEN]; 764 int err; 765 766 /* If port is egress mirrored, the shared buffer size should be 767 * updated according to the mtu value 768 */ 769 if (mlxsw_sp_span_is_egress_mirror(port)) { 770 u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, mtu); 771 772 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize); 773 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); 774 if (err) { 775 netdev_err(port->dev, "Could not update shared buffer for mirroring\n"); 776 return err; 777 } 778 } 779 780 return 0; 781 } 782 783 static struct mlxsw_sp_span_inspected_port * 784 mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry, 785 enum mlxsw_sp_span_type type, 786 struct mlxsw_sp_port *port, 787 bool bind) 788 { 789 struct mlxsw_sp_span_inspected_port *p; 790 791 list_for_each_entry(p, &span_entry->bound_ports_list, list) 792 if (type == p->type && 793 port->local_port == p->local_port && 794 bind == p->bound) 795 return p; 796 return NULL; 797 } 798 799 static int 800 mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, 801 struct mlxsw_sp_span_entry *span_entry, 802 enum mlxsw_sp_span_type type, 803 bool bind) 804 { 805 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; 806 char mpar_pl[MLXSW_REG_MPAR_LEN]; 807 int pa_id = span_entry->id; 808 809 /* bind the port to the SPAN entry */ 810 mlxsw_reg_mpar_pack(mpar_pl, port->local_port, 811 (enum mlxsw_reg_mpar_i_e)type, bind, pa_id); 812 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl); 813 } 814 815 static int 816 mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port, 817 struct mlxsw_sp_span_entry *span_entry, 818 enum mlxsw_sp_span_type type, 819 bool bind) 820 { 821 struct mlxsw_sp_span_inspected_port *inspected_port; 822 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; 823 char sbib_pl[MLXSW_REG_SBIB_LEN]; 824 int i; 825 int err; 826 827 /* A given (source port, direction) can only be bound to one analyzer, 828 * so if a binding is requested, check for conflicts. 829 */ 830 if (bind) 831 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 832 struct mlxsw_sp_span_entry *curr = 833 &mlxsw_sp->span.entries[i]; 834 835 if (mlxsw_sp_span_entry_bound_port_find(curr, type, 836 port, bind)) 837 return -EEXIST; 838 } 839 840 /* if it is an egress SPAN, bind a shared buffer to it */ 841 if (type == MLXSW_SP_SPAN_EGRESS) { 842 u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, 843 port->dev->mtu); 844 845 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize); 846 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); 847 if (err) { 848 netdev_err(port->dev, "Could not create shared buffer for mirroring\n"); 849 return err; 850 } 851 } 852 853 if (bind) { 854 err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type, 855 true); 856 if (err) 857 goto err_port_bind; 858 } 859 860 inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL); 861 if (!inspected_port) { 862 err = -ENOMEM; 863 goto err_inspected_port_alloc; 864 } 865 inspected_port->local_port = port->local_port; 866 inspected_port->type = type; 867 inspected_port->bound = bind; 868 list_add_tail(&inspected_port->list, &span_entry->bound_ports_list); 869 870 return 0; 871 872 err_inspected_port_alloc: 873 if (bind) 874 mlxsw_sp_span_inspected_port_bind(port, span_entry, type, 875 false); 876 err_port_bind: 877 if (type == MLXSW_SP_SPAN_EGRESS) { 878 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0); 879 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); 880 } 881 return err; 882 } 883 884 static void 885 mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port, 886 struct mlxsw_sp_span_entry *span_entry, 887 enum mlxsw_sp_span_type type, 888 bool bind) 889 { 890 struct mlxsw_sp_span_inspected_port *inspected_port; 891 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; 892 char sbib_pl[MLXSW_REG_SBIB_LEN]; 893 894 inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type, 895 port, bind); 896 if (!inspected_port) 897 return; 898 899 if (bind) 900 mlxsw_sp_span_inspected_port_bind(port, span_entry, type, 901 false); 902 /* remove the SBIB buffer if it was egress SPAN */ 903 if (type == MLXSW_SP_SPAN_EGRESS) { 904 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0); 905 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); 906 } 907 908 mlxsw_sp_span_entry_put(mlxsw_sp, span_entry); 909 910 list_del(&inspected_port->list); 911 kfree(inspected_port); 912 } 913 914 static const struct mlxsw_sp_span_entry_ops * 915 mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp, 916 const struct net_device *to_dev) 917 { 918 size_t i; 919 920 for (i = 0; i < ARRAY_SIZE(mlxsw_sp_span_entry_types); ++i) 921 if (mlxsw_sp_span_entry_types[i]->can_handle(to_dev)) 922 return mlxsw_sp_span_entry_types[i]; 923 924 return NULL; 925 } 926 927 int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from, 928 const struct net_device *to_dev, 929 enum mlxsw_sp_span_type type, bool bind, 930 int *p_span_id) 931 { 932 struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp; 933 const struct mlxsw_sp_span_entry_ops *ops; 934 struct mlxsw_sp_span_parms sparms = {NULL}; 935 struct mlxsw_sp_span_entry *span_entry; 936 int err; 937 938 ops = mlxsw_sp_span_entry_ops(mlxsw_sp, to_dev); 939 if (!ops) { 940 netdev_err(to_dev, "Cannot mirror to %s", to_dev->name); 941 return -EOPNOTSUPP; 942 } 943 944 err = ops->parms(to_dev, &sparms); 945 if (err) 946 return err; 947 948 span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms); 949 if (!span_entry) 950 return -ENOBUFS; 951 952 netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n", 953 span_entry->id); 954 955 err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind); 956 if (err) 957 goto err_port_bind; 958 959 *p_span_id = span_entry->id; 960 return 0; 961 962 err_port_bind: 963 mlxsw_sp_span_entry_put(mlxsw_sp, span_entry); 964 return err; 965 } 966 967 void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id, 968 enum mlxsw_sp_span_type type, bool bind) 969 { 970 struct mlxsw_sp_span_entry *span_entry; 971 972 span_entry = mlxsw_sp_span_entry_find_by_id(from->mlxsw_sp, span_id); 973 if (!span_entry) { 974 netdev_err(from->dev, "no span entry found\n"); 975 return; 976 } 977 978 netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n", 979 span_entry->id); 980 mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind); 981 } 982 983 void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp) 984 { 985 int i; 986 int err; 987 988 ASSERT_RTNL(); 989 for (i = 0; i < mlxsw_sp->span.entries_count; i++) { 990 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i]; 991 struct mlxsw_sp_span_parms sparms = {NULL}; 992 993 if (!curr->ref_count) 994 continue; 995 996 err = curr->ops->parms(curr->to_dev, &sparms); 997 if (err) 998 continue; 999 1000 if (memcmp(&sparms, &curr->parms, sizeof(sparms))) { 1001 mlxsw_sp_span_entry_deconfigure(curr); 1002 mlxsw_sp_span_entry_configure(mlxsw_sp, curr, sparms); 1003 } 1004 } 1005 } 1006