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