1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */ 3 4 #include <linux/etherdevice.h> 5 #include <linux/inetdevice.h> 6 #include <net/netevent.h> 7 #include <linux/idr.h> 8 #include <net/dst_metadata.h> 9 #include <net/arp.h> 10 11 #include "cmsg.h" 12 #include "main.h" 13 #include "../nfp_net_repr.h" 14 #include "../nfp_net.h" 15 16 #define NFP_FL_MAX_ROUTES 32 17 18 #define NFP_TUN_PRE_TUN_RULE_LIMIT 32 19 #define NFP_TUN_PRE_TUN_RULE_DEL BIT(0) 20 #define NFP_TUN_PRE_TUN_IDX_BIT BIT(3) 21 #define NFP_TUN_PRE_TUN_IPV6_BIT BIT(7) 22 23 /** 24 * struct nfp_tun_pre_tun_rule - rule matched before decap 25 * @flags: options for the rule offset 26 * @port_idx: index of destination MAC address for the rule 27 * @vlan_tci: VLAN info associated with MAC 28 * @host_ctx_id: stats context of rule to update 29 */ 30 struct nfp_tun_pre_tun_rule { 31 __be32 flags; 32 __be16 port_idx; 33 __be16 vlan_tci; 34 __be32 host_ctx_id; 35 }; 36 37 /** 38 * struct nfp_tun_active_tuns - periodic message of active tunnels 39 * @seq: sequence number of the message 40 * @count: number of tunnels report in message 41 * @flags: options part of the request 42 * @tun_info.ipv4: dest IPv4 address of active route 43 * @tun_info.egress_port: port the encapsulated packet egressed 44 * @tun_info.extra: reserved for future use 45 * @tun_info: tunnels that have sent traffic in reported period 46 */ 47 struct nfp_tun_active_tuns { 48 __be32 seq; 49 __be32 count; 50 __be32 flags; 51 struct route_ip_info { 52 __be32 ipv4; 53 __be32 egress_port; 54 __be32 extra[2]; 55 } tun_info[]; 56 }; 57 58 /** 59 * struct nfp_tun_active_tuns_v6 - periodic message of active IPv6 tunnels 60 * @seq: sequence number of the message 61 * @count: number of tunnels report in message 62 * @flags: options part of the request 63 * @tun_info.ipv6: dest IPv6 address of active route 64 * @tun_info.egress_port: port the encapsulated packet egressed 65 * @tun_info.extra: reserved for future use 66 * @tun_info: tunnels that have sent traffic in reported period 67 */ 68 struct nfp_tun_active_tuns_v6 { 69 __be32 seq; 70 __be32 count; 71 __be32 flags; 72 struct route_ip_info_v6 { 73 struct in6_addr ipv6; 74 __be32 egress_port; 75 __be32 extra[2]; 76 } tun_info[]; 77 }; 78 79 /** 80 * struct nfp_tun_req_route_ipv4 - NFP requests a route/neighbour lookup 81 * @ingress_port: ingress port of packet that signalled request 82 * @ipv4_addr: destination ipv4 address for route 83 * @reserved: reserved for future use 84 */ 85 struct nfp_tun_req_route_ipv4 { 86 __be32 ingress_port; 87 __be32 ipv4_addr; 88 __be32 reserved[2]; 89 }; 90 91 /** 92 * struct nfp_tun_req_route_ipv6 - NFP requests an IPv6 route/neighbour lookup 93 * @ingress_port: ingress port of packet that signalled request 94 * @ipv6_addr: destination ipv6 address for route 95 */ 96 struct nfp_tun_req_route_ipv6 { 97 __be32 ingress_port; 98 struct in6_addr ipv6_addr; 99 }; 100 101 /** 102 * struct nfp_offloaded_route - routes that are offloaded to the NFP 103 * @list: list pointer 104 * @ip_add: destination of route - can be IPv4 or IPv6 105 */ 106 struct nfp_offloaded_route { 107 struct list_head list; 108 u8 ip_add[]; 109 }; 110 111 #define NFP_FL_IPV4_ADDRS_MAX 32 112 113 /** 114 * struct nfp_tun_ipv4_addr - set the IP address list on the NFP 115 * @count: number of IPs populated in the array 116 * @ipv4_addr: array of IPV4_ADDRS_MAX 32 bit IPv4 addresses 117 */ 118 struct nfp_tun_ipv4_addr { 119 __be32 count; 120 __be32 ipv4_addr[NFP_FL_IPV4_ADDRS_MAX]; 121 }; 122 123 /** 124 * struct nfp_ipv4_addr_entry - cached IPv4 addresses 125 * @ipv4_addr: IP address 126 * @ref_count: number of rules currently using this IP 127 * @list: list pointer 128 */ 129 struct nfp_ipv4_addr_entry { 130 __be32 ipv4_addr; 131 int ref_count; 132 struct list_head list; 133 }; 134 135 #define NFP_FL_IPV6_ADDRS_MAX 4 136 137 /** 138 * struct nfp_tun_ipv6_addr - set the IP address list on the NFP 139 * @count: number of IPs populated in the array 140 * @ipv6_addr: array of IPV6_ADDRS_MAX 128 bit IPv6 addresses 141 */ 142 struct nfp_tun_ipv6_addr { 143 __be32 count; 144 struct in6_addr ipv6_addr[NFP_FL_IPV6_ADDRS_MAX]; 145 }; 146 147 #define NFP_TUN_MAC_OFFLOAD_DEL_FLAG 0x2 148 149 /** 150 * struct nfp_tun_mac_addr_offload - configure MAC address of tunnel EP on NFP 151 * @flags: MAC address offload options 152 * @count: number of MAC addresses in the message (should be 1) 153 * @index: index of MAC address in the lookup table 154 * @addr: interface MAC address 155 */ 156 struct nfp_tun_mac_addr_offload { 157 __be16 flags; 158 __be16 count; 159 __be16 index; 160 u8 addr[ETH_ALEN]; 161 }; 162 163 /** 164 * struct nfp_neigh_update_work - update neighbour information to nfp 165 * @work: Work queue for writing neigh to the nfp 166 * @n: neighbour entry 167 * @app: Back pointer to app 168 */ 169 struct nfp_neigh_update_work { 170 struct work_struct work; 171 struct neighbour *n; 172 struct nfp_app *app; 173 }; 174 175 enum nfp_flower_mac_offload_cmd { 176 NFP_TUNNEL_MAC_OFFLOAD_ADD = 0, 177 NFP_TUNNEL_MAC_OFFLOAD_DEL = 1, 178 NFP_TUNNEL_MAC_OFFLOAD_MOD = 2, 179 }; 180 181 #define NFP_MAX_MAC_INDEX 0xff 182 183 /** 184 * struct nfp_tun_offloaded_mac - hashtable entry for an offloaded MAC 185 * @ht_node: Hashtable entry 186 * @addr: Offloaded MAC address 187 * @index: Offloaded index for given MAC address 188 * @ref_count: Number of devs using this MAC address 189 * @repr_list: List of reprs sharing this MAC address 190 * @bridge_count: Number of bridge/internal devs with MAC 191 */ 192 struct nfp_tun_offloaded_mac { 193 struct rhash_head ht_node; 194 u8 addr[ETH_ALEN]; 195 u16 index; 196 int ref_count; 197 struct list_head repr_list; 198 int bridge_count; 199 }; 200 201 static const struct rhashtable_params offloaded_macs_params = { 202 .key_offset = offsetof(struct nfp_tun_offloaded_mac, addr), 203 .head_offset = offsetof(struct nfp_tun_offloaded_mac, ht_node), 204 .key_len = ETH_ALEN, 205 .automatic_shrinking = true, 206 }; 207 208 void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb) 209 { 210 struct nfp_tun_active_tuns *payload; 211 struct net_device *netdev; 212 int count, i, pay_len; 213 struct neighbour *n; 214 __be32 ipv4_addr; 215 u32 port; 216 217 payload = nfp_flower_cmsg_get_data(skb); 218 count = be32_to_cpu(payload->count); 219 if (count > NFP_FL_MAX_ROUTES) { 220 nfp_flower_cmsg_warn(app, "Tunnel keep-alive request exceeds max routes.\n"); 221 return; 222 } 223 224 pay_len = nfp_flower_cmsg_get_data_len(skb); 225 if (pay_len != struct_size(payload, tun_info, count)) { 226 nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n"); 227 return; 228 } 229 230 rcu_read_lock(); 231 for (i = 0; i < count; i++) { 232 ipv4_addr = payload->tun_info[i].ipv4; 233 port = be32_to_cpu(payload->tun_info[i].egress_port); 234 netdev = nfp_app_dev_get(app, port, NULL); 235 if (!netdev) 236 continue; 237 238 n = neigh_lookup(&arp_tbl, &ipv4_addr, netdev); 239 if (!n) 240 continue; 241 242 /* Update the used timestamp of neighbour */ 243 neigh_event_send(n, NULL); 244 neigh_release(n); 245 } 246 rcu_read_unlock(); 247 } 248 249 void nfp_tunnel_keep_alive_v6(struct nfp_app *app, struct sk_buff *skb) 250 { 251 #if IS_ENABLED(CONFIG_IPV6) 252 struct nfp_tun_active_tuns_v6 *payload; 253 struct net_device *netdev; 254 int count, i, pay_len; 255 struct neighbour *n; 256 void *ipv6_add; 257 u32 port; 258 259 payload = nfp_flower_cmsg_get_data(skb); 260 count = be32_to_cpu(payload->count); 261 if (count > NFP_FL_IPV6_ADDRS_MAX) { 262 nfp_flower_cmsg_warn(app, "IPv6 tunnel keep-alive request exceeds max routes.\n"); 263 return; 264 } 265 266 pay_len = nfp_flower_cmsg_get_data_len(skb); 267 if (pay_len != struct_size(payload, tun_info, count)) { 268 nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n"); 269 return; 270 } 271 272 rcu_read_lock(); 273 for (i = 0; i < count; i++) { 274 ipv6_add = &payload->tun_info[i].ipv6; 275 port = be32_to_cpu(payload->tun_info[i].egress_port); 276 netdev = nfp_app_dev_get(app, port, NULL); 277 if (!netdev) 278 continue; 279 280 n = neigh_lookup(&nd_tbl, ipv6_add, netdev); 281 if (!n) 282 continue; 283 284 /* Update the used timestamp of neighbour */ 285 neigh_event_send(n, NULL); 286 neigh_release(n); 287 } 288 rcu_read_unlock(); 289 #endif 290 } 291 292 static int 293 nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata, 294 gfp_t flag) 295 { 296 struct nfp_flower_priv *priv = app->priv; 297 struct sk_buff *skb; 298 unsigned char *msg; 299 300 if (!(priv->flower_ext_feats & NFP_FL_FEATS_DECAP_V2) && 301 (mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH || 302 mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6)) 303 plen -= sizeof(struct nfp_tun_neigh_ext); 304 305 if (!(priv->flower_ext_feats & NFP_FL_FEATS_TUNNEL_NEIGH_LAG) && 306 (mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH || 307 mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6)) 308 plen -= sizeof(struct nfp_tun_neigh_lag); 309 310 skb = nfp_flower_cmsg_alloc(app, plen, mtype, flag); 311 if (!skb) 312 return -ENOMEM; 313 314 msg = nfp_flower_cmsg_get_data(skb); 315 memcpy(msg, pdata, nfp_flower_cmsg_get_data_len(skb)); 316 317 nfp_ctrl_tx(app->ctrl, skb); 318 return 0; 319 } 320 321 static void 322 nfp_tun_mutual_link(struct nfp_predt_entry *predt, 323 struct nfp_neigh_entry *neigh) 324 { 325 struct nfp_fl_payload *flow_pay = predt->flow_pay; 326 struct nfp_tun_neigh_ext *ext; 327 struct nfp_tun_neigh *common; 328 329 if (flow_pay->pre_tun_rule.is_ipv6 != neigh->is_ipv6) 330 return; 331 332 /* In the case of bonding it is possible that there might already 333 * be a flow linked (as the MAC address gets shared). If a flow 334 * is already linked just return. 335 */ 336 if (neigh->flow) 337 return; 338 339 common = neigh->is_ipv6 ? 340 &((struct nfp_tun_neigh_v6 *)neigh->payload)->common : 341 &((struct nfp_tun_neigh_v4 *)neigh->payload)->common; 342 ext = neigh->is_ipv6 ? 343 &((struct nfp_tun_neigh_v6 *)neigh->payload)->ext : 344 &((struct nfp_tun_neigh_v4 *)neigh->payload)->ext; 345 346 if (memcmp(flow_pay->pre_tun_rule.loc_mac, 347 common->src_addr, ETH_ALEN) || 348 memcmp(flow_pay->pre_tun_rule.rem_mac, 349 common->dst_addr, ETH_ALEN)) 350 return; 351 352 list_add(&neigh->list_head, &predt->nn_list); 353 neigh->flow = predt; 354 ext->host_ctx = flow_pay->meta.host_ctx_id; 355 ext->vlan_tci = flow_pay->pre_tun_rule.vlan_tci; 356 ext->vlan_tpid = flow_pay->pre_tun_rule.vlan_tpid; 357 } 358 359 static void 360 nfp_tun_link_predt_entries(struct nfp_app *app, 361 struct nfp_neigh_entry *nn_entry) 362 { 363 struct nfp_flower_priv *priv = app->priv; 364 struct nfp_predt_entry *predt, *tmp; 365 366 list_for_each_entry_safe(predt, tmp, &priv->predt_list, list_head) { 367 nfp_tun_mutual_link(predt, nn_entry); 368 } 369 } 370 371 void nfp_tun_link_and_update_nn_entries(struct nfp_app *app, 372 struct nfp_predt_entry *predt) 373 { 374 struct nfp_flower_priv *priv = app->priv; 375 struct nfp_neigh_entry *nn_entry; 376 struct rhashtable_iter iter; 377 size_t neigh_size; 378 u8 type; 379 380 rhashtable_walk_enter(&priv->neigh_table, &iter); 381 rhashtable_walk_start(&iter); 382 while ((nn_entry = rhashtable_walk_next(&iter)) != NULL) { 383 if (IS_ERR(nn_entry)) 384 continue; 385 nfp_tun_mutual_link(predt, nn_entry); 386 neigh_size = nn_entry->is_ipv6 ? 387 sizeof(struct nfp_tun_neigh_v6) : 388 sizeof(struct nfp_tun_neigh_v4); 389 type = nn_entry->is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 : 390 NFP_FLOWER_CMSG_TYPE_TUN_NEIGH; 391 nfp_flower_xmit_tun_conf(app, type, neigh_size, 392 nn_entry->payload, 393 GFP_ATOMIC); 394 } 395 rhashtable_walk_stop(&iter); 396 rhashtable_walk_exit(&iter); 397 } 398 399 static void nfp_tun_cleanup_nn_entries(struct nfp_app *app) 400 { 401 struct nfp_flower_priv *priv = app->priv; 402 struct nfp_neigh_entry *neigh; 403 struct nfp_tun_neigh_ext *ext; 404 struct rhashtable_iter iter; 405 size_t neigh_size; 406 u8 type; 407 408 rhashtable_walk_enter(&priv->neigh_table, &iter); 409 rhashtable_walk_start(&iter); 410 while ((neigh = rhashtable_walk_next(&iter)) != NULL) { 411 if (IS_ERR(neigh)) 412 continue; 413 ext = neigh->is_ipv6 ? 414 &((struct nfp_tun_neigh_v6 *)neigh->payload)->ext : 415 &((struct nfp_tun_neigh_v4 *)neigh->payload)->ext; 416 ext->host_ctx = cpu_to_be32(U32_MAX); 417 ext->vlan_tpid = cpu_to_be16(U16_MAX); 418 ext->vlan_tci = cpu_to_be16(U16_MAX); 419 420 neigh_size = neigh->is_ipv6 ? 421 sizeof(struct nfp_tun_neigh_v6) : 422 sizeof(struct nfp_tun_neigh_v4); 423 type = neigh->is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 : 424 NFP_FLOWER_CMSG_TYPE_TUN_NEIGH; 425 nfp_flower_xmit_tun_conf(app, type, neigh_size, neigh->payload, 426 GFP_ATOMIC); 427 428 rhashtable_remove_fast(&priv->neigh_table, &neigh->ht_node, 429 neigh_table_params); 430 if (neigh->flow) 431 list_del(&neigh->list_head); 432 kfree(neigh); 433 } 434 rhashtable_walk_stop(&iter); 435 rhashtable_walk_exit(&iter); 436 } 437 438 void nfp_tun_unlink_and_update_nn_entries(struct nfp_app *app, 439 struct nfp_predt_entry *predt) 440 { 441 struct nfp_neigh_entry *neigh, *tmp; 442 struct nfp_tun_neigh_ext *ext; 443 size_t neigh_size; 444 u8 type; 445 446 list_for_each_entry_safe(neigh, tmp, &predt->nn_list, list_head) { 447 ext = neigh->is_ipv6 ? 448 &((struct nfp_tun_neigh_v6 *)neigh->payload)->ext : 449 &((struct nfp_tun_neigh_v4 *)neigh->payload)->ext; 450 neigh->flow = NULL; 451 ext->host_ctx = cpu_to_be32(U32_MAX); 452 ext->vlan_tpid = cpu_to_be16(U16_MAX); 453 ext->vlan_tci = cpu_to_be16(U16_MAX); 454 list_del(&neigh->list_head); 455 neigh_size = neigh->is_ipv6 ? 456 sizeof(struct nfp_tun_neigh_v6) : 457 sizeof(struct nfp_tun_neigh_v4); 458 type = neigh->is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 : 459 NFP_FLOWER_CMSG_TYPE_TUN_NEIGH; 460 nfp_flower_xmit_tun_conf(app, type, neigh_size, neigh->payload, 461 GFP_ATOMIC); 462 } 463 } 464 465 static void 466 nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app, 467 void *flow, struct neighbour *neigh, bool is_ipv6, 468 bool override) 469 { 470 bool neigh_invalid = !(neigh->nud_state & NUD_VALID) || neigh->dead; 471 size_t neigh_size = is_ipv6 ? sizeof(struct nfp_tun_neigh_v6) : 472 sizeof(struct nfp_tun_neigh_v4); 473 unsigned long cookie = (unsigned long)neigh; 474 struct nfp_flower_priv *priv = app->priv; 475 struct nfp_tun_neigh_lag lag_info; 476 struct nfp_neigh_entry *nn_entry; 477 u32 port_id; 478 u8 mtype; 479 480 port_id = nfp_flower_get_port_id_from_netdev(app, netdev); 481 if (!port_id) 482 return; 483 484 if ((port_id & NFP_FL_LAG_OUT) == NFP_FL_LAG_OUT) { 485 memset(&lag_info, 0, sizeof(struct nfp_tun_neigh_lag)); 486 nfp_flower_lag_get_info_from_netdev(app, netdev, &lag_info); 487 } 488 489 spin_lock_bh(&priv->predt_lock); 490 nn_entry = rhashtable_lookup_fast(&priv->neigh_table, &cookie, 491 neigh_table_params); 492 if (!nn_entry && !neigh_invalid) { 493 struct nfp_tun_neigh_ext *ext; 494 struct nfp_tun_neigh_lag *lag; 495 struct nfp_tun_neigh *common; 496 497 nn_entry = kzalloc(sizeof(*nn_entry) + neigh_size, 498 GFP_ATOMIC); 499 if (!nn_entry) 500 goto err; 501 502 nn_entry->payload = (char *)&nn_entry[1]; 503 nn_entry->neigh_cookie = cookie; 504 nn_entry->is_ipv6 = is_ipv6; 505 nn_entry->flow = NULL; 506 if (is_ipv6) { 507 struct flowi6 *flowi6 = (struct flowi6 *)flow; 508 struct nfp_tun_neigh_v6 *payload; 509 510 payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload; 511 payload->src_ipv6 = flowi6->saddr; 512 payload->dst_ipv6 = flowi6->daddr; 513 common = &payload->common; 514 ext = &payload->ext; 515 lag = &payload->lag; 516 mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6; 517 } else { 518 struct flowi4 *flowi4 = (struct flowi4 *)flow; 519 struct nfp_tun_neigh_v4 *payload; 520 521 payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload; 522 payload->src_ipv4 = flowi4->saddr; 523 payload->dst_ipv4 = flowi4->daddr; 524 common = &payload->common; 525 ext = &payload->ext; 526 lag = &payload->lag; 527 mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH; 528 } 529 ext->host_ctx = cpu_to_be32(U32_MAX); 530 ext->vlan_tpid = cpu_to_be16(U16_MAX); 531 ext->vlan_tci = cpu_to_be16(U16_MAX); 532 ether_addr_copy(common->src_addr, netdev->dev_addr); 533 neigh_ha_snapshot(common->dst_addr, neigh, netdev); 534 535 if ((port_id & NFP_FL_LAG_OUT) == NFP_FL_LAG_OUT) 536 memcpy(lag, &lag_info, sizeof(struct nfp_tun_neigh_lag)); 537 common->port_id = cpu_to_be32(port_id); 538 539 if (rhashtable_insert_fast(&priv->neigh_table, 540 &nn_entry->ht_node, 541 neigh_table_params)) 542 goto err; 543 544 nfp_tun_link_predt_entries(app, nn_entry); 545 nfp_flower_xmit_tun_conf(app, mtype, neigh_size, 546 nn_entry->payload, 547 GFP_ATOMIC); 548 } else if (nn_entry && neigh_invalid) { 549 if (is_ipv6) { 550 struct flowi6 *flowi6 = (struct flowi6 *)flow; 551 struct nfp_tun_neigh_v6 *payload; 552 553 payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload; 554 memset(payload, 0, sizeof(struct nfp_tun_neigh_v6)); 555 payload->dst_ipv6 = flowi6->daddr; 556 mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6; 557 } else { 558 struct flowi4 *flowi4 = (struct flowi4 *)flow; 559 struct nfp_tun_neigh_v4 *payload; 560 561 payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload; 562 memset(payload, 0, sizeof(struct nfp_tun_neigh_v4)); 563 payload->dst_ipv4 = flowi4->daddr; 564 mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH; 565 } 566 /* Trigger ARP to verify invalid neighbour state. */ 567 neigh_event_send(neigh, NULL); 568 rhashtable_remove_fast(&priv->neigh_table, 569 &nn_entry->ht_node, 570 neigh_table_params); 571 572 nfp_flower_xmit_tun_conf(app, mtype, neigh_size, 573 nn_entry->payload, 574 GFP_ATOMIC); 575 576 if (nn_entry->flow) 577 list_del(&nn_entry->list_head); 578 kfree(nn_entry); 579 } else if (nn_entry && !neigh_invalid) { 580 struct nfp_tun_neigh *common; 581 u8 dst_addr[ETH_ALEN]; 582 bool is_mac_change; 583 584 if (is_ipv6) { 585 struct nfp_tun_neigh_v6 *payload; 586 587 payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload; 588 common = &payload->common; 589 mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6; 590 } else { 591 struct nfp_tun_neigh_v4 *payload; 592 593 payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload; 594 common = &payload->common; 595 mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH; 596 } 597 598 ether_addr_copy(dst_addr, common->dst_addr); 599 neigh_ha_snapshot(common->dst_addr, neigh, netdev); 600 is_mac_change = !ether_addr_equal(dst_addr, common->dst_addr); 601 if (override || is_mac_change) { 602 if (is_mac_change && nn_entry->flow) { 603 list_del(&nn_entry->list_head); 604 nn_entry->flow = NULL; 605 } 606 nfp_tun_link_predt_entries(app, nn_entry); 607 nfp_flower_xmit_tun_conf(app, mtype, neigh_size, 608 nn_entry->payload, 609 GFP_ATOMIC); 610 } 611 } 612 613 spin_unlock_bh(&priv->predt_lock); 614 return; 615 616 err: 617 kfree(nn_entry); 618 spin_unlock_bh(&priv->predt_lock); 619 nfp_flower_cmsg_warn(app, "Neighbour configuration failed.\n"); 620 } 621 622 static void 623 nfp_tun_release_neigh_update_work(struct nfp_neigh_update_work *update_work) 624 { 625 neigh_release(update_work->n); 626 kfree(update_work); 627 } 628 629 static void nfp_tun_neigh_update(struct work_struct *work) 630 { 631 struct nfp_neigh_update_work *update_work; 632 struct nfp_app *app; 633 struct neighbour *n; 634 bool neigh_invalid; 635 int err; 636 637 update_work = container_of(work, struct nfp_neigh_update_work, work); 638 app = update_work->app; 639 n = update_work->n; 640 641 if (!nfp_flower_get_port_id_from_netdev(app, n->dev)) 642 goto out; 643 644 #if IS_ENABLED(CONFIG_INET) 645 neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead; 646 if (n->tbl->family == AF_INET6) { 647 #if IS_ENABLED(CONFIG_IPV6) 648 struct flowi6 flow6 = {}; 649 650 flow6.daddr = *(struct in6_addr *)n->primary_key; 651 if (!neigh_invalid) { 652 struct dst_entry *dst; 653 /* Use ipv6_dst_lookup_flow to populate flow6->saddr 654 * and other fields. This information is only needed 655 * for new entries, lookup can be skipped when an entry 656 * gets invalidated - as only the daddr is needed for 657 * deleting. 658 */ 659 dst = ip6_dst_lookup_flow(dev_net(n->dev), NULL, 660 &flow6, NULL); 661 if (IS_ERR(dst)) 662 goto out; 663 664 dst_release(dst); 665 } 666 nfp_tun_write_neigh(n->dev, app, &flow6, n, true, false); 667 #endif /* CONFIG_IPV6 */ 668 } else { 669 struct flowi4 flow4 = {}; 670 671 flow4.daddr = *(__be32 *)n->primary_key; 672 if (!neigh_invalid) { 673 struct rtable *rt; 674 /* Use ip_route_output_key to populate flow4->saddr and 675 * other fields. This information is only needed for 676 * new entries, lookup can be skipped when an entry 677 * gets invalidated - as only the daddr is needed for 678 * deleting. 679 */ 680 rt = ip_route_output_key(dev_net(n->dev), &flow4); 681 err = PTR_ERR_OR_ZERO(rt); 682 if (err) 683 goto out; 684 685 ip_rt_put(rt); 686 } 687 nfp_tun_write_neigh(n->dev, app, &flow4, n, false, false); 688 } 689 #endif /* CONFIG_INET */ 690 out: 691 nfp_tun_release_neigh_update_work(update_work); 692 } 693 694 static struct nfp_neigh_update_work * 695 nfp_tun_alloc_neigh_update_work(struct nfp_app *app, struct neighbour *n) 696 { 697 struct nfp_neigh_update_work *update_work; 698 699 update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC); 700 if (!update_work) 701 return NULL; 702 703 INIT_WORK(&update_work->work, nfp_tun_neigh_update); 704 neigh_hold(n); 705 update_work->n = n; 706 update_work->app = app; 707 708 return update_work; 709 } 710 711 static int 712 nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, 713 void *ptr) 714 { 715 struct nfp_neigh_update_work *update_work; 716 struct nfp_flower_priv *app_priv; 717 struct netevent_redirect *redir; 718 struct neighbour *n; 719 struct nfp_app *app; 720 721 switch (event) { 722 case NETEVENT_REDIRECT: 723 redir = (struct netevent_redirect *)ptr; 724 n = redir->neigh; 725 break; 726 case NETEVENT_NEIGH_UPDATE: 727 n = (struct neighbour *)ptr; 728 break; 729 default: 730 return NOTIFY_DONE; 731 } 732 #if IS_ENABLED(CONFIG_IPV6) 733 if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl) 734 #else 735 if (n->tbl != &arp_tbl) 736 #endif 737 return NOTIFY_DONE; 738 739 app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb); 740 app = app_priv->app; 741 update_work = nfp_tun_alloc_neigh_update_work(app, n); 742 if (!update_work) 743 return NOTIFY_DONE; 744 745 queue_work(system_highpri_wq, &update_work->work); 746 747 return NOTIFY_DONE; 748 } 749 750 void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) 751 { 752 struct nfp_tun_req_route_ipv4 *payload; 753 struct net_device *netdev; 754 struct flowi4 flow = {}; 755 struct neighbour *n; 756 struct rtable *rt; 757 int err; 758 759 payload = nfp_flower_cmsg_get_data(skb); 760 761 rcu_read_lock(); 762 netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); 763 if (!netdev) 764 goto fail_rcu_unlock; 765 dev_hold(netdev); 766 767 flow.daddr = payload->ipv4_addr; 768 flow.flowi4_proto = IPPROTO_UDP; 769 770 #if IS_ENABLED(CONFIG_INET) 771 /* Do a route lookup on same namespace as ingress port. */ 772 rt = ip_route_output_key(dev_net(netdev), &flow); 773 err = PTR_ERR_OR_ZERO(rt); 774 if (err) 775 goto fail_rcu_unlock; 776 #else 777 goto fail_rcu_unlock; 778 #endif 779 780 /* Get the neighbour entry for the lookup */ 781 n = dst_neigh_lookup(&rt->dst, &flow.daddr); 782 ip_rt_put(rt); 783 if (!n) 784 goto fail_rcu_unlock; 785 rcu_read_unlock(); 786 787 nfp_tun_write_neigh(n->dev, app, &flow, n, false, true); 788 neigh_release(n); 789 dev_put(netdev); 790 return; 791 792 fail_rcu_unlock: 793 rcu_read_unlock(); 794 dev_put(netdev); 795 nfp_flower_cmsg_warn(app, "Requested route not found.\n"); 796 } 797 798 void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb) 799 { 800 struct nfp_tun_req_route_ipv6 *payload; 801 struct net_device *netdev; 802 struct flowi6 flow = {}; 803 struct dst_entry *dst; 804 struct neighbour *n; 805 806 payload = nfp_flower_cmsg_get_data(skb); 807 808 rcu_read_lock(); 809 netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); 810 if (!netdev) 811 goto fail_rcu_unlock; 812 dev_hold(netdev); 813 814 flow.daddr = payload->ipv6_addr; 815 flow.flowi6_proto = IPPROTO_UDP; 816 817 #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) 818 dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(netdev), NULL, &flow, 819 NULL); 820 if (IS_ERR(dst)) 821 goto fail_rcu_unlock; 822 #else 823 goto fail_rcu_unlock; 824 #endif 825 826 n = dst_neigh_lookup(dst, &flow.daddr); 827 dst_release(dst); 828 if (!n) 829 goto fail_rcu_unlock; 830 rcu_read_unlock(); 831 832 nfp_tun_write_neigh(n->dev, app, &flow, n, true, true); 833 neigh_release(n); 834 dev_put(netdev); 835 return; 836 837 fail_rcu_unlock: 838 rcu_read_unlock(); 839 dev_put(netdev); 840 nfp_flower_cmsg_warn(app, "Requested IPv6 route not found.\n"); 841 } 842 843 static void nfp_tun_write_ipv4_list(struct nfp_app *app) 844 { 845 struct nfp_flower_priv *priv = app->priv; 846 struct nfp_ipv4_addr_entry *entry; 847 struct nfp_tun_ipv4_addr payload; 848 struct list_head *ptr, *storage; 849 int count; 850 851 memset(&payload, 0, sizeof(struct nfp_tun_ipv4_addr)); 852 mutex_lock(&priv->tun.ipv4_off_lock); 853 count = 0; 854 list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) { 855 if (count >= NFP_FL_IPV4_ADDRS_MAX) { 856 mutex_unlock(&priv->tun.ipv4_off_lock); 857 nfp_flower_cmsg_warn(app, "IPv4 offload exceeds limit.\n"); 858 return; 859 } 860 entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list); 861 payload.ipv4_addr[count++] = entry->ipv4_addr; 862 } 863 payload.count = cpu_to_be32(count); 864 mutex_unlock(&priv->tun.ipv4_off_lock); 865 866 nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_IPS, 867 sizeof(struct nfp_tun_ipv4_addr), 868 &payload, GFP_KERNEL); 869 } 870 871 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4) 872 { 873 struct nfp_flower_priv *priv = app->priv; 874 struct nfp_ipv4_addr_entry *entry; 875 struct list_head *ptr, *storage; 876 877 mutex_lock(&priv->tun.ipv4_off_lock); 878 list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) { 879 entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list); 880 if (entry->ipv4_addr == ipv4) { 881 entry->ref_count++; 882 mutex_unlock(&priv->tun.ipv4_off_lock); 883 return; 884 } 885 } 886 887 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 888 if (!entry) { 889 mutex_unlock(&priv->tun.ipv4_off_lock); 890 nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n"); 891 return; 892 } 893 entry->ipv4_addr = ipv4; 894 entry->ref_count = 1; 895 list_add_tail(&entry->list, &priv->tun.ipv4_off_list); 896 mutex_unlock(&priv->tun.ipv4_off_lock); 897 898 nfp_tun_write_ipv4_list(app); 899 } 900 901 void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4) 902 { 903 struct nfp_flower_priv *priv = app->priv; 904 struct nfp_ipv4_addr_entry *entry; 905 struct list_head *ptr, *storage; 906 907 mutex_lock(&priv->tun.ipv4_off_lock); 908 list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) { 909 entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list); 910 if (entry->ipv4_addr == ipv4) { 911 entry->ref_count--; 912 if (!entry->ref_count) { 913 list_del(&entry->list); 914 kfree(entry); 915 } 916 break; 917 } 918 } 919 mutex_unlock(&priv->tun.ipv4_off_lock); 920 921 nfp_tun_write_ipv4_list(app); 922 } 923 924 static void nfp_tun_write_ipv6_list(struct nfp_app *app) 925 { 926 struct nfp_flower_priv *priv = app->priv; 927 struct nfp_ipv6_addr_entry *entry; 928 struct nfp_tun_ipv6_addr payload; 929 int count = 0; 930 931 memset(&payload, 0, sizeof(struct nfp_tun_ipv6_addr)); 932 mutex_lock(&priv->tun.ipv6_off_lock); 933 list_for_each_entry(entry, &priv->tun.ipv6_off_list, list) { 934 if (count >= NFP_FL_IPV6_ADDRS_MAX) { 935 nfp_flower_cmsg_warn(app, "Too many IPv6 tunnel endpoint addresses, some cannot be offloaded.\n"); 936 break; 937 } 938 payload.ipv6_addr[count++] = entry->ipv6_addr; 939 } 940 mutex_unlock(&priv->tun.ipv6_off_lock); 941 payload.count = cpu_to_be32(count); 942 943 nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_IPS_V6, 944 sizeof(struct nfp_tun_ipv6_addr), 945 &payload, GFP_KERNEL); 946 } 947 948 struct nfp_ipv6_addr_entry * 949 nfp_tunnel_add_ipv6_off(struct nfp_app *app, struct in6_addr *ipv6) 950 { 951 struct nfp_flower_priv *priv = app->priv; 952 struct nfp_ipv6_addr_entry *entry; 953 954 mutex_lock(&priv->tun.ipv6_off_lock); 955 list_for_each_entry(entry, &priv->tun.ipv6_off_list, list) 956 if (!memcmp(&entry->ipv6_addr, ipv6, sizeof(*ipv6))) { 957 entry->ref_count++; 958 mutex_unlock(&priv->tun.ipv6_off_lock); 959 return entry; 960 } 961 962 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 963 if (!entry) { 964 mutex_unlock(&priv->tun.ipv6_off_lock); 965 nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n"); 966 return NULL; 967 } 968 entry->ipv6_addr = *ipv6; 969 entry->ref_count = 1; 970 list_add_tail(&entry->list, &priv->tun.ipv6_off_list); 971 mutex_unlock(&priv->tun.ipv6_off_lock); 972 973 nfp_tun_write_ipv6_list(app); 974 975 return entry; 976 } 977 978 void 979 nfp_tunnel_put_ipv6_off(struct nfp_app *app, struct nfp_ipv6_addr_entry *entry) 980 { 981 struct nfp_flower_priv *priv = app->priv; 982 bool freed = false; 983 984 mutex_lock(&priv->tun.ipv6_off_lock); 985 if (!--entry->ref_count) { 986 list_del(&entry->list); 987 kfree(entry); 988 freed = true; 989 } 990 mutex_unlock(&priv->tun.ipv6_off_lock); 991 992 if (freed) 993 nfp_tun_write_ipv6_list(app); 994 } 995 996 static int 997 __nfp_tunnel_offload_mac(struct nfp_app *app, const u8 *mac, u16 idx, bool del) 998 { 999 struct nfp_tun_mac_addr_offload payload; 1000 1001 memset(&payload, 0, sizeof(payload)); 1002 1003 if (del) 1004 payload.flags = cpu_to_be16(NFP_TUN_MAC_OFFLOAD_DEL_FLAG); 1005 1006 /* FW supports multiple MACs per cmsg but restrict to single. */ 1007 payload.count = cpu_to_be16(1); 1008 payload.index = cpu_to_be16(idx); 1009 ether_addr_copy(payload.addr, mac); 1010 1011 return nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC, 1012 sizeof(struct nfp_tun_mac_addr_offload), 1013 &payload, GFP_KERNEL); 1014 } 1015 1016 static bool nfp_tunnel_port_is_phy_repr(int port) 1017 { 1018 if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) == 1019 NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT) 1020 return true; 1021 1022 return false; 1023 } 1024 1025 static u16 nfp_tunnel_get_mac_idx_from_phy_port_id(int port) 1026 { 1027 return port << 8 | NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT; 1028 } 1029 1030 static u16 nfp_tunnel_get_global_mac_idx_from_ida(int id) 1031 { 1032 return id << 8 | NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT; 1033 } 1034 1035 static int nfp_tunnel_get_ida_from_global_mac_idx(u16 nfp_mac_idx) 1036 { 1037 return nfp_mac_idx >> 8; 1038 } 1039 1040 static bool nfp_tunnel_is_mac_idx_global(u16 nfp_mac_idx) 1041 { 1042 return (nfp_mac_idx & 0xff) == NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT; 1043 } 1044 1045 static struct nfp_tun_offloaded_mac * 1046 nfp_tunnel_lookup_offloaded_macs(struct nfp_app *app, const u8 *mac) 1047 { 1048 struct nfp_flower_priv *priv = app->priv; 1049 1050 return rhashtable_lookup_fast(&priv->tun.offloaded_macs, mac, 1051 offloaded_macs_params); 1052 } 1053 1054 static void 1055 nfp_tunnel_offloaded_macs_inc_ref_and_link(struct nfp_tun_offloaded_mac *entry, 1056 struct net_device *netdev, bool mod) 1057 { 1058 if (nfp_netdev_is_nfp_repr(netdev)) { 1059 struct nfp_flower_repr_priv *repr_priv; 1060 struct nfp_repr *repr; 1061 1062 repr = netdev_priv(netdev); 1063 repr_priv = repr->app_priv; 1064 1065 /* If modifing MAC, remove repr from old list first. */ 1066 if (mod) 1067 list_del(&repr_priv->mac_list); 1068 1069 list_add_tail(&repr_priv->mac_list, &entry->repr_list); 1070 } else if (nfp_flower_is_supported_bridge(netdev)) { 1071 entry->bridge_count++; 1072 } 1073 1074 entry->ref_count++; 1075 } 1076 1077 static int 1078 nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev, 1079 int port, bool mod) 1080 { 1081 struct nfp_flower_priv *priv = app->priv; 1082 struct nfp_tun_offloaded_mac *entry; 1083 int ida_idx = -1, err; 1084 u16 nfp_mac_idx = 0; 1085 1086 entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); 1087 if (entry && (nfp_tunnel_is_mac_idx_global(entry->index) || netif_is_lag_port(netdev))) { 1088 if (entry->bridge_count || 1089 !nfp_flower_is_supported_bridge(netdev)) { 1090 nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, 1091 netdev, mod); 1092 return 0; 1093 } 1094 1095 /* MAC is global but matches need to go to pre_tun table. */ 1096 nfp_mac_idx = entry->index | NFP_TUN_PRE_TUN_IDX_BIT; 1097 } 1098 1099 if (!nfp_mac_idx) { 1100 /* Assign a global index if non-repr or MAC is now shared. */ 1101 if (entry || !port) { 1102 ida_idx = ida_alloc_max(&priv->tun.mac_off_ids, 1103 NFP_MAX_MAC_INDEX, GFP_KERNEL); 1104 if (ida_idx < 0) 1105 return ida_idx; 1106 1107 nfp_mac_idx = 1108 nfp_tunnel_get_global_mac_idx_from_ida(ida_idx); 1109 1110 if (nfp_flower_is_supported_bridge(netdev)) 1111 nfp_mac_idx |= NFP_TUN_PRE_TUN_IDX_BIT; 1112 1113 } else { 1114 nfp_mac_idx = 1115 nfp_tunnel_get_mac_idx_from_phy_port_id(port); 1116 } 1117 } 1118 1119 if (!entry) { 1120 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 1121 if (!entry) { 1122 err = -ENOMEM; 1123 goto err_free_ida; 1124 } 1125 1126 ether_addr_copy(entry->addr, netdev->dev_addr); 1127 INIT_LIST_HEAD(&entry->repr_list); 1128 1129 if (rhashtable_insert_fast(&priv->tun.offloaded_macs, 1130 &entry->ht_node, 1131 offloaded_macs_params)) { 1132 err = -ENOMEM; 1133 goto err_free_entry; 1134 } 1135 } 1136 1137 err = __nfp_tunnel_offload_mac(app, netdev->dev_addr, 1138 nfp_mac_idx, false); 1139 if (err) { 1140 /* If not shared then free. */ 1141 if (!entry->ref_count) 1142 goto err_remove_hash; 1143 goto err_free_ida; 1144 } 1145 1146 entry->index = nfp_mac_idx; 1147 nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, netdev, mod); 1148 1149 return 0; 1150 1151 err_remove_hash: 1152 rhashtable_remove_fast(&priv->tun.offloaded_macs, &entry->ht_node, 1153 offloaded_macs_params); 1154 err_free_entry: 1155 kfree(entry); 1156 err_free_ida: 1157 if (ida_idx != -1) 1158 ida_free(&priv->tun.mac_off_ids, ida_idx); 1159 1160 return err; 1161 } 1162 1163 static int 1164 nfp_tunnel_del_shared_mac(struct nfp_app *app, struct net_device *netdev, 1165 const u8 *mac, bool mod) 1166 { 1167 struct nfp_flower_priv *priv = app->priv; 1168 struct nfp_flower_repr_priv *repr_priv; 1169 struct nfp_tun_offloaded_mac *entry; 1170 struct nfp_repr *repr; 1171 u16 nfp_mac_idx; 1172 int ida_idx; 1173 1174 entry = nfp_tunnel_lookup_offloaded_macs(app, mac); 1175 if (!entry) 1176 return 0; 1177 1178 entry->ref_count--; 1179 /* If del is part of a mod then mac_list is still in use elsewhere. */ 1180 if (nfp_netdev_is_nfp_repr(netdev) && !mod) { 1181 repr = netdev_priv(netdev); 1182 repr_priv = repr->app_priv; 1183 list_del(&repr_priv->mac_list); 1184 } 1185 1186 if (nfp_flower_is_supported_bridge(netdev)) { 1187 entry->bridge_count--; 1188 1189 if (!entry->bridge_count && entry->ref_count) { 1190 nfp_mac_idx = entry->index & ~NFP_TUN_PRE_TUN_IDX_BIT; 1191 if (__nfp_tunnel_offload_mac(app, mac, nfp_mac_idx, 1192 false)) { 1193 nfp_flower_cmsg_warn(app, "MAC offload index revert failed on %s.\n", 1194 netdev_name(netdev)); 1195 return 0; 1196 } 1197 1198 entry->index = nfp_mac_idx; 1199 return 0; 1200 } 1201 } 1202 1203 /* If MAC is now used by 1 repr set the offloaded MAC index to port. */ 1204 if (entry->ref_count == 1 && list_is_singular(&entry->repr_list)) { 1205 int port, err; 1206 1207 repr_priv = list_first_entry(&entry->repr_list, 1208 struct nfp_flower_repr_priv, 1209 mac_list); 1210 repr = repr_priv->nfp_repr; 1211 port = nfp_repr_get_port_id(repr->netdev); 1212 nfp_mac_idx = nfp_tunnel_get_mac_idx_from_phy_port_id(port); 1213 err = __nfp_tunnel_offload_mac(app, mac, nfp_mac_idx, false); 1214 if (err) { 1215 nfp_flower_cmsg_warn(app, "MAC offload index revert failed on %s.\n", 1216 netdev_name(netdev)); 1217 return 0; 1218 } 1219 1220 ida_idx = nfp_tunnel_get_ida_from_global_mac_idx(entry->index); 1221 ida_free(&priv->tun.mac_off_ids, ida_idx); 1222 entry->index = nfp_mac_idx; 1223 return 0; 1224 } 1225 1226 if (entry->ref_count) 1227 return 0; 1228 1229 WARN_ON_ONCE(rhashtable_remove_fast(&priv->tun.offloaded_macs, 1230 &entry->ht_node, 1231 offloaded_macs_params)); 1232 1233 if (nfp_flower_is_supported_bridge(netdev)) 1234 nfp_mac_idx = entry->index & ~NFP_TUN_PRE_TUN_IDX_BIT; 1235 else 1236 nfp_mac_idx = entry->index; 1237 1238 /* If MAC has global ID then extract and free the ida entry. */ 1239 if (nfp_tunnel_is_mac_idx_global(nfp_mac_idx)) { 1240 ida_idx = nfp_tunnel_get_ida_from_global_mac_idx(entry->index); 1241 ida_free(&priv->tun.mac_off_ids, ida_idx); 1242 } 1243 1244 kfree(entry); 1245 1246 return __nfp_tunnel_offload_mac(app, mac, 0, true); 1247 } 1248 1249 static int 1250 nfp_tunnel_offload_mac(struct nfp_app *app, struct net_device *netdev, 1251 enum nfp_flower_mac_offload_cmd cmd) 1252 { 1253 struct nfp_flower_non_repr_priv *nr_priv = NULL; 1254 bool non_repr = false, *mac_offloaded; 1255 u8 *off_mac = NULL; 1256 int err, port = 0; 1257 1258 if (nfp_netdev_is_nfp_repr(netdev)) { 1259 struct nfp_flower_repr_priv *repr_priv; 1260 struct nfp_repr *repr; 1261 1262 repr = netdev_priv(netdev); 1263 if (repr->app != app) 1264 return 0; 1265 1266 repr_priv = repr->app_priv; 1267 if (repr_priv->on_bridge) 1268 return 0; 1269 1270 mac_offloaded = &repr_priv->mac_offloaded; 1271 off_mac = &repr_priv->offloaded_mac_addr[0]; 1272 port = nfp_repr_get_port_id(netdev); 1273 if (!nfp_tunnel_port_is_phy_repr(port)) 1274 return 0; 1275 } else if (nfp_fl_is_netdev_to_offload(netdev)) { 1276 nr_priv = nfp_flower_non_repr_priv_get(app, netdev); 1277 if (!nr_priv) 1278 return -ENOMEM; 1279 1280 mac_offloaded = &nr_priv->mac_offloaded; 1281 off_mac = &nr_priv->offloaded_mac_addr[0]; 1282 non_repr = true; 1283 } else { 1284 return 0; 1285 } 1286 1287 if (!is_valid_ether_addr(netdev->dev_addr)) { 1288 err = -EINVAL; 1289 goto err_put_non_repr_priv; 1290 } 1291 1292 if (cmd == NFP_TUNNEL_MAC_OFFLOAD_MOD && !*mac_offloaded) 1293 cmd = NFP_TUNNEL_MAC_OFFLOAD_ADD; 1294 1295 switch (cmd) { 1296 case NFP_TUNNEL_MAC_OFFLOAD_ADD: 1297 err = nfp_tunnel_add_shared_mac(app, netdev, port, false); 1298 if (err) 1299 goto err_put_non_repr_priv; 1300 1301 if (non_repr) 1302 __nfp_flower_non_repr_priv_get(nr_priv); 1303 1304 *mac_offloaded = true; 1305 ether_addr_copy(off_mac, netdev->dev_addr); 1306 break; 1307 case NFP_TUNNEL_MAC_OFFLOAD_DEL: 1308 /* Only attempt delete if add was successful. */ 1309 if (!*mac_offloaded) 1310 break; 1311 1312 if (non_repr) 1313 __nfp_flower_non_repr_priv_put(nr_priv); 1314 1315 *mac_offloaded = false; 1316 1317 err = nfp_tunnel_del_shared_mac(app, netdev, netdev->dev_addr, 1318 false); 1319 if (err) 1320 goto err_put_non_repr_priv; 1321 1322 break; 1323 case NFP_TUNNEL_MAC_OFFLOAD_MOD: 1324 /* Ignore if changing to the same address. */ 1325 if (ether_addr_equal(netdev->dev_addr, off_mac)) 1326 break; 1327 1328 err = nfp_tunnel_add_shared_mac(app, netdev, port, true); 1329 if (err) 1330 goto err_put_non_repr_priv; 1331 1332 /* Delete the previous MAC address. */ 1333 err = nfp_tunnel_del_shared_mac(app, netdev, off_mac, true); 1334 if (err) 1335 nfp_flower_cmsg_warn(app, "Failed to remove offload of replaced MAC addr on %s.\n", 1336 netdev_name(netdev)); 1337 1338 ether_addr_copy(off_mac, netdev->dev_addr); 1339 break; 1340 default: 1341 err = -EINVAL; 1342 goto err_put_non_repr_priv; 1343 } 1344 1345 if (non_repr) 1346 __nfp_flower_non_repr_priv_put(nr_priv); 1347 1348 return 0; 1349 1350 err_put_non_repr_priv: 1351 if (non_repr) 1352 __nfp_flower_non_repr_priv_put(nr_priv); 1353 1354 return err; 1355 } 1356 1357 int nfp_tunnel_mac_event_handler(struct nfp_app *app, 1358 struct net_device *netdev, 1359 unsigned long event, void *ptr) 1360 { 1361 int err; 1362 1363 if (event == NETDEV_DOWN) { 1364 err = nfp_tunnel_offload_mac(app, netdev, 1365 NFP_TUNNEL_MAC_OFFLOAD_DEL); 1366 if (err) 1367 nfp_flower_cmsg_warn(app, "Failed to delete offload MAC on %s.\n", 1368 netdev_name(netdev)); 1369 } else if (event == NETDEV_UP) { 1370 err = nfp_tunnel_offload_mac(app, netdev, 1371 NFP_TUNNEL_MAC_OFFLOAD_ADD); 1372 if (err) 1373 nfp_flower_cmsg_warn(app, "Failed to offload MAC on %s.\n", 1374 netdev_name(netdev)); 1375 } else if (event == NETDEV_CHANGEADDR) { 1376 /* Only offload addr change if netdev is already up. */ 1377 if (!(netdev->flags & IFF_UP)) 1378 return NOTIFY_OK; 1379 1380 err = nfp_tunnel_offload_mac(app, netdev, 1381 NFP_TUNNEL_MAC_OFFLOAD_MOD); 1382 if (err) 1383 nfp_flower_cmsg_warn(app, "Failed to offload MAC change on %s.\n", 1384 netdev_name(netdev)); 1385 } else if (event == NETDEV_CHANGEUPPER) { 1386 /* If a repr is attached to a bridge then tunnel packets 1387 * entering the physical port are directed through the bridge 1388 * datapath and cannot be directly detunneled. Therefore, 1389 * associated offloaded MACs and indexes should not be used 1390 * by fw for detunneling. 1391 */ 1392 struct netdev_notifier_changeupper_info *info = ptr; 1393 struct net_device *upper = info->upper_dev; 1394 struct nfp_flower_repr_priv *repr_priv; 1395 struct nfp_repr *repr; 1396 1397 if (!nfp_netdev_is_nfp_repr(netdev) || 1398 !nfp_flower_is_supported_bridge(upper)) 1399 return NOTIFY_OK; 1400 1401 repr = netdev_priv(netdev); 1402 if (repr->app != app) 1403 return NOTIFY_OK; 1404 1405 repr_priv = repr->app_priv; 1406 1407 if (info->linking) { 1408 if (nfp_tunnel_offload_mac(app, netdev, 1409 NFP_TUNNEL_MAC_OFFLOAD_DEL)) 1410 nfp_flower_cmsg_warn(app, "Failed to delete offloaded MAC on %s.\n", 1411 netdev_name(netdev)); 1412 repr_priv->on_bridge = true; 1413 } else { 1414 repr_priv->on_bridge = false; 1415 1416 if (!(netdev->flags & IFF_UP)) 1417 return NOTIFY_OK; 1418 1419 if (nfp_tunnel_offload_mac(app, netdev, 1420 NFP_TUNNEL_MAC_OFFLOAD_ADD)) 1421 nfp_flower_cmsg_warn(app, "Failed to offload MAC on %s.\n", 1422 netdev_name(netdev)); 1423 } 1424 } 1425 return NOTIFY_OK; 1426 } 1427 1428 int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app, 1429 struct nfp_fl_payload *flow) 1430 { 1431 struct nfp_flower_priv *app_priv = app->priv; 1432 struct nfp_tun_offloaded_mac *mac_entry; 1433 struct nfp_flower_meta_tci *key_meta; 1434 struct nfp_tun_pre_tun_rule payload; 1435 struct net_device *internal_dev; 1436 int err; 1437 1438 if (app_priv->pre_tun_rule_cnt == NFP_TUN_PRE_TUN_RULE_LIMIT) 1439 return -ENOSPC; 1440 1441 memset(&payload, 0, sizeof(struct nfp_tun_pre_tun_rule)); 1442 1443 internal_dev = flow->pre_tun_rule.dev; 1444 payload.vlan_tci = flow->pre_tun_rule.vlan_tci; 1445 payload.host_ctx_id = flow->meta.host_ctx_id; 1446 1447 /* Lookup MAC index for the pre-tunnel rule egress device. 1448 * Note that because the device is always an internal port, it will 1449 * have a constant global index so does not need to be tracked. 1450 */ 1451 mac_entry = nfp_tunnel_lookup_offloaded_macs(app, 1452 internal_dev->dev_addr); 1453 if (!mac_entry) 1454 return -ENOENT; 1455 1456 /* Set/clear IPV6 bit. cpu_to_be16() swap will lead to MSB being 1457 * set/clear for port_idx. 1458 */ 1459 key_meta = (struct nfp_flower_meta_tci *)flow->unmasked_data; 1460 if (key_meta->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV6) 1461 mac_entry->index |= NFP_TUN_PRE_TUN_IPV6_BIT; 1462 else 1463 mac_entry->index &= ~NFP_TUN_PRE_TUN_IPV6_BIT; 1464 1465 payload.port_idx = cpu_to_be16(mac_entry->index); 1466 1467 /* Copy mac id and vlan to flow - dev may not exist at delete time. */ 1468 flow->pre_tun_rule.vlan_tci = payload.vlan_tci; 1469 flow->pre_tun_rule.port_idx = payload.port_idx; 1470 1471 err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE, 1472 sizeof(struct nfp_tun_pre_tun_rule), 1473 (unsigned char *)&payload, GFP_KERNEL); 1474 if (err) 1475 return err; 1476 1477 app_priv->pre_tun_rule_cnt++; 1478 1479 return 0; 1480 } 1481 1482 int nfp_flower_xmit_pre_tun_del_flow(struct nfp_app *app, 1483 struct nfp_fl_payload *flow) 1484 { 1485 struct nfp_flower_priv *app_priv = app->priv; 1486 struct nfp_tun_pre_tun_rule payload; 1487 u32 tmp_flags = 0; 1488 int err; 1489 1490 memset(&payload, 0, sizeof(struct nfp_tun_pre_tun_rule)); 1491 1492 tmp_flags |= NFP_TUN_PRE_TUN_RULE_DEL; 1493 payload.flags = cpu_to_be32(tmp_flags); 1494 payload.vlan_tci = flow->pre_tun_rule.vlan_tci; 1495 payload.port_idx = flow->pre_tun_rule.port_idx; 1496 1497 err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE, 1498 sizeof(struct nfp_tun_pre_tun_rule), 1499 (unsigned char *)&payload, GFP_KERNEL); 1500 if (err) 1501 return err; 1502 1503 app_priv->pre_tun_rule_cnt--; 1504 1505 return 0; 1506 } 1507 1508 int nfp_tunnel_config_start(struct nfp_app *app) 1509 { 1510 struct nfp_flower_priv *priv = app->priv; 1511 int err; 1512 1513 /* Initialise rhash for MAC offload tracking. */ 1514 err = rhashtable_init(&priv->tun.offloaded_macs, 1515 &offloaded_macs_params); 1516 if (err) 1517 return err; 1518 1519 ida_init(&priv->tun.mac_off_ids); 1520 1521 /* Initialise priv data for IPv4/v6 offloading. */ 1522 mutex_init(&priv->tun.ipv4_off_lock); 1523 INIT_LIST_HEAD(&priv->tun.ipv4_off_list); 1524 mutex_init(&priv->tun.ipv6_off_lock); 1525 INIT_LIST_HEAD(&priv->tun.ipv6_off_list); 1526 1527 /* Initialise priv data for neighbour offloading. */ 1528 priv->tun.neigh_nb.notifier_call = nfp_tun_neigh_event_handler; 1529 1530 err = register_netevent_notifier(&priv->tun.neigh_nb); 1531 if (err) { 1532 rhashtable_free_and_destroy(&priv->tun.offloaded_macs, 1533 nfp_check_rhashtable_empty, NULL); 1534 return err; 1535 } 1536 1537 return 0; 1538 } 1539 1540 void nfp_tunnel_config_stop(struct nfp_app *app) 1541 { 1542 struct nfp_flower_priv *priv = app->priv; 1543 struct nfp_ipv4_addr_entry *ip_entry; 1544 struct list_head *ptr, *storage; 1545 1546 unregister_netevent_notifier(&priv->tun.neigh_nb); 1547 1548 ida_destroy(&priv->tun.mac_off_ids); 1549 1550 /* Free any memory that may be occupied by ipv4 list. */ 1551 list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) { 1552 ip_entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list); 1553 list_del(&ip_entry->list); 1554 kfree(ip_entry); 1555 } 1556 1557 mutex_destroy(&priv->tun.ipv6_off_lock); 1558 1559 /* Destroy rhash. Entries should be cleaned on netdev notifier unreg. */ 1560 rhashtable_free_and_destroy(&priv->tun.offloaded_macs, 1561 nfp_check_rhashtable_empty, NULL); 1562 1563 nfp_tun_cleanup_nn_entries(app); 1564 } 1565