1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4 #include <net/ip_tunnels.h> 5 #include <net/ip6_tunnel.h> 6 #include <net/inet_ecn.h> 7 8 #include "spectrum_ipip.h" 9 #include "reg.h" 10 11 struct ip_tunnel_parm 12 mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev) 13 { 14 struct ip_tunnel *tun = netdev_priv(ol_dev); 15 16 return tun->parms; 17 } 18 19 struct __ip6_tnl_parm 20 mlxsw_sp_ipip_netdev_parms6(const struct net_device *ol_dev) 21 { 22 struct ip6_tnl *tun = netdev_priv(ol_dev); 23 24 return tun->parms; 25 } 26 27 static bool mlxsw_sp_ipip_parms4_has_ikey(const struct ip_tunnel_parm *parms) 28 { 29 return !!(parms->i_flags & TUNNEL_KEY); 30 } 31 32 static bool mlxsw_sp_ipip_parms6_has_ikey(const struct __ip6_tnl_parm *parms) 33 { 34 return !!(parms->i_flags & TUNNEL_KEY); 35 } 36 37 static bool mlxsw_sp_ipip_parms4_has_okey(const struct ip_tunnel_parm *parms) 38 { 39 return !!(parms->o_flags & TUNNEL_KEY); 40 } 41 42 static bool mlxsw_sp_ipip_parms6_has_okey(const struct __ip6_tnl_parm *parms) 43 { 44 return !!(parms->o_flags & TUNNEL_KEY); 45 } 46 47 static u32 mlxsw_sp_ipip_parms4_ikey(const struct ip_tunnel_parm *parms) 48 { 49 return mlxsw_sp_ipip_parms4_has_ikey(parms) ? 50 be32_to_cpu(parms->i_key) : 0; 51 } 52 53 static u32 mlxsw_sp_ipip_parms6_ikey(const struct __ip6_tnl_parm *parms) 54 { 55 return mlxsw_sp_ipip_parms6_has_ikey(parms) ? 56 be32_to_cpu(parms->i_key) : 0; 57 } 58 59 static u32 mlxsw_sp_ipip_parms4_okey(const struct ip_tunnel_parm *parms) 60 { 61 return mlxsw_sp_ipip_parms4_has_okey(parms) ? 62 be32_to_cpu(parms->o_key) : 0; 63 } 64 65 static u32 mlxsw_sp_ipip_parms6_okey(const struct __ip6_tnl_parm *parms) 66 { 67 return mlxsw_sp_ipip_parms6_has_okey(parms) ? 68 be32_to_cpu(parms->o_key) : 0; 69 } 70 71 static union mlxsw_sp_l3addr 72 mlxsw_sp_ipip_parms4_saddr(const struct ip_tunnel_parm *parms) 73 { 74 return (union mlxsw_sp_l3addr) { .addr4 = parms->iph.saddr }; 75 } 76 77 static union mlxsw_sp_l3addr 78 mlxsw_sp_ipip_parms6_saddr(const struct __ip6_tnl_parm *parms) 79 { 80 return (union mlxsw_sp_l3addr) { .addr6 = parms->laddr }; 81 } 82 83 static union mlxsw_sp_l3addr 84 mlxsw_sp_ipip_parms4_daddr(const struct ip_tunnel_parm *parms) 85 { 86 return (union mlxsw_sp_l3addr) { .addr4 = parms->iph.daddr }; 87 } 88 89 static union mlxsw_sp_l3addr 90 mlxsw_sp_ipip_parms6_daddr(const struct __ip6_tnl_parm *parms) 91 { 92 return (union mlxsw_sp_l3addr) { .addr6 = parms->raddr }; 93 } 94 95 union mlxsw_sp_l3addr 96 mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto, 97 const struct net_device *ol_dev) 98 { 99 struct ip_tunnel_parm parms4; 100 struct __ip6_tnl_parm parms6; 101 102 switch (proto) { 103 case MLXSW_SP_L3_PROTO_IPV4: 104 parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev); 105 return mlxsw_sp_ipip_parms4_saddr(&parms4); 106 case MLXSW_SP_L3_PROTO_IPV6: 107 parms6 = mlxsw_sp_ipip_netdev_parms6(ol_dev); 108 return mlxsw_sp_ipip_parms6_saddr(&parms6); 109 } 110 111 WARN_ON(1); 112 return (union mlxsw_sp_l3addr) {0}; 113 } 114 115 static __be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev) 116 { 117 118 struct ip_tunnel_parm parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev); 119 120 return mlxsw_sp_ipip_parms4_daddr(&parms4).addr4; 121 } 122 123 static union mlxsw_sp_l3addr 124 mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto, 125 const struct net_device *ol_dev) 126 { 127 struct ip_tunnel_parm parms4; 128 struct __ip6_tnl_parm parms6; 129 130 switch (proto) { 131 case MLXSW_SP_L3_PROTO_IPV4: 132 parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev); 133 return mlxsw_sp_ipip_parms4_daddr(&parms4); 134 case MLXSW_SP_L3_PROTO_IPV6: 135 parms6 = mlxsw_sp_ipip_netdev_parms6(ol_dev); 136 return mlxsw_sp_ipip_parms6_daddr(&parms6); 137 } 138 139 WARN_ON(1); 140 return (union mlxsw_sp_l3addr) {0}; 141 } 142 143 bool mlxsw_sp_l3addr_is_zero(union mlxsw_sp_l3addr addr) 144 { 145 union mlxsw_sp_l3addr naddr = {0}; 146 147 return !memcmp(&addr, &naddr, sizeof(naddr)); 148 } 149 150 static struct mlxsw_sp_ipip_parms 151 mlxsw_sp_ipip_netdev_parms_init_gre4(const struct net_device *ol_dev) 152 { 153 struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev); 154 155 return (struct mlxsw_sp_ipip_parms) { 156 .proto = MLXSW_SP_L3_PROTO_IPV4, 157 .saddr = mlxsw_sp_ipip_parms4_saddr(&parms), 158 .daddr = mlxsw_sp_ipip_parms4_daddr(&parms), 159 .link = parms.link, 160 .ikey = mlxsw_sp_ipip_parms4_ikey(&parms), 161 .okey = mlxsw_sp_ipip_parms4_okey(&parms), 162 }; 163 } 164 165 static int 166 mlxsw_sp_ipip_nexthop_update_gre4(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 167 struct mlxsw_sp_ipip_entry *ipip_entry, 168 bool force, char *ratr_pl) 169 { 170 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb); 171 __be32 daddr4 = mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev); 172 enum mlxsw_reg_ratr_op op; 173 174 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY : 175 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY; 176 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_IPIP, 177 adj_index, rif_index); 178 mlxsw_reg_ratr_ipip4_entry_pack(ratr_pl, be32_to_cpu(daddr4)); 179 180 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl); 181 } 182 183 static int 184 mlxsw_sp_ipip_decap_config_gre4(struct mlxsw_sp *mlxsw_sp, 185 struct mlxsw_sp_ipip_entry *ipip_entry, 186 u32 tunnel_index) 187 { 188 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb); 189 u16 ul_rif_id = mlxsw_sp_ipip_lb_ul_rif_id(ipip_entry->ol_lb); 190 char rtdp_pl[MLXSW_REG_RTDP_LEN]; 191 struct ip_tunnel_parm parms; 192 unsigned int type_check; 193 bool has_ikey; 194 u32 daddr4; 195 u32 ikey; 196 197 parms = mlxsw_sp_ipip_netdev_parms4(ipip_entry->ol_dev); 198 has_ikey = mlxsw_sp_ipip_parms4_has_ikey(&parms); 199 ikey = mlxsw_sp_ipip_parms4_ikey(&parms); 200 201 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index); 202 mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_id); 203 204 type_check = has_ikey ? 205 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY : 206 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE; 207 208 /* Linux demuxes tunnels based on packet SIP (which must match tunnel 209 * remote IP). Thus configure decap so that it filters out packets that 210 * are not IPv4 or have the wrong SIP. IPIP_DECAP_ERROR trap is 211 * generated for packets that fail this criterion. Linux then handles 212 * such packets in slow path and generates ICMP destination unreachable. 213 */ 214 daddr4 = be32_to_cpu(mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev)); 215 mlxsw_reg_rtdp_ipip4_pack(rtdp_pl, rif_index, 216 MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV4, 217 type_check, has_ikey, daddr4, ikey); 218 219 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl); 220 } 221 222 static bool mlxsw_sp_ipip_tunnel_complete(enum mlxsw_sp_l3proto proto, 223 const struct net_device *ol_dev) 224 { 225 union mlxsw_sp_l3addr saddr = mlxsw_sp_ipip_netdev_saddr(proto, ol_dev); 226 union mlxsw_sp_l3addr daddr = mlxsw_sp_ipip_netdev_daddr(proto, ol_dev); 227 228 /* Tunnels with unset local or remote address are valid in Linux and 229 * used for lightweight tunnels (LWT) and Non-Broadcast Multi-Access 230 * (NBMA) tunnels. In principle these can be offloaded, but the driver 231 * currently doesn't support this. So punt. 232 */ 233 return !mlxsw_sp_l3addr_is_zero(saddr) && 234 !mlxsw_sp_l3addr_is_zero(daddr); 235 } 236 237 static bool mlxsw_sp_ipip_can_offload_gre4(const struct mlxsw_sp *mlxsw_sp, 238 const struct net_device *ol_dev) 239 { 240 struct ip_tunnel *tunnel = netdev_priv(ol_dev); 241 __be16 okflags = TUNNEL_KEY; /* We can't offload any other features. */ 242 bool inherit_ttl = tunnel->parms.iph.ttl == 0; 243 bool inherit_tos = tunnel->parms.iph.tos & 0x1; 244 245 return (tunnel->parms.i_flags & ~okflags) == 0 && 246 (tunnel->parms.o_flags & ~okflags) == 0 && 247 inherit_ttl && inherit_tos && 248 mlxsw_sp_ipip_tunnel_complete(MLXSW_SP_L3_PROTO_IPV4, ol_dev); 249 } 250 251 static struct mlxsw_sp_rif_ipip_lb_config 252 mlxsw_sp_ipip_ol_loopback_config_gre4(struct mlxsw_sp *mlxsw_sp, 253 const struct net_device *ol_dev) 254 { 255 struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev); 256 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; 257 258 lb_ipipt = mlxsw_sp_ipip_parms4_has_okey(&parms) ? 259 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP : 260 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP; 261 return (struct mlxsw_sp_rif_ipip_lb_config){ 262 .lb_ipipt = lb_ipipt, 263 .okey = mlxsw_sp_ipip_parms4_okey(&parms), 264 .ul_protocol = MLXSW_SP_L3_PROTO_IPV4, 265 .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV4, 266 ol_dev), 267 }; 268 } 269 270 static int 271 mlxsw_sp_ipip_ol_netdev_change_gre(struct mlxsw_sp *mlxsw_sp, 272 struct mlxsw_sp_ipip_entry *ipip_entry, 273 const struct mlxsw_sp_ipip_parms *new_parms, 274 struct netlink_ext_ack *extack) 275 { 276 const struct mlxsw_sp_ipip_parms *old_parms = &ipip_entry->parms; 277 bool update_tunnel = false; 278 bool update_decap = false; 279 bool update_nhs = false; 280 int err = 0; 281 282 if (!mlxsw_sp_l3addr_eq(&new_parms->saddr, &old_parms->saddr)) { 283 u16 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev); 284 285 /* Since the local address has changed, if there is another 286 * tunnel with a matching saddr, both need to be demoted. 287 */ 288 if (mlxsw_sp_ipip_demote_tunnel_by_saddr(mlxsw_sp, 289 new_parms->proto, 290 new_parms->saddr, 291 ul_tb_id, 292 ipip_entry)) { 293 mlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry); 294 return 0; 295 } 296 297 update_tunnel = true; 298 } else if (old_parms->okey != new_parms->okey || 299 old_parms->link != new_parms->link) { 300 update_tunnel = true; 301 } else if (!mlxsw_sp_l3addr_eq(&new_parms->daddr, &old_parms->daddr)) { 302 update_nhs = true; 303 } else if (old_parms->ikey != new_parms->ikey) { 304 update_decap = true; 305 } 306 307 if (update_tunnel) 308 err = __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry, 309 true, true, true, 310 extack); 311 else if (update_nhs) 312 err = __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry, 313 false, false, true, 314 extack); 315 else if (update_decap) 316 err = __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry, 317 false, false, false, 318 extack); 319 if (err) 320 return err; 321 322 ipip_entry->parms = *new_parms; 323 return 0; 324 } 325 326 static int 327 mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp, 328 struct mlxsw_sp_ipip_entry *ipip_entry, 329 struct netlink_ext_ack *extack) 330 { 331 struct mlxsw_sp_ipip_parms new_parms; 332 333 new_parms = mlxsw_sp_ipip_netdev_parms_init_gre4(ipip_entry->ol_dev); 334 return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry, 335 &new_parms, extack); 336 } 337 338 static int 339 mlxsw_sp_ipip_rem_addr_set_gre4(struct mlxsw_sp *mlxsw_sp, 340 struct mlxsw_sp_ipip_entry *ipip_entry) 341 { 342 return 0; 343 } 344 345 static void 346 mlxsw_sp_ipip_rem_addr_unset_gre4(struct mlxsw_sp *mlxsw_sp, 347 const struct mlxsw_sp_ipip_entry *ipip_entry) 348 { 349 } 350 351 static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = { 352 .dev_type = ARPHRD_IPGRE, 353 .ul_proto = MLXSW_SP_L3_PROTO_IPV4, 354 .inc_parsing_depth = false, 355 .parms_init = mlxsw_sp_ipip_netdev_parms_init_gre4, 356 .nexthop_update = mlxsw_sp_ipip_nexthop_update_gre4, 357 .decap_config = mlxsw_sp_ipip_decap_config_gre4, 358 .can_offload = mlxsw_sp_ipip_can_offload_gre4, 359 .ol_loopback_config = mlxsw_sp_ipip_ol_loopback_config_gre4, 360 .ol_netdev_change = mlxsw_sp_ipip_ol_netdev_change_gre4, 361 .rem_ip_addr_set = mlxsw_sp_ipip_rem_addr_set_gre4, 362 .rem_ip_addr_unset = mlxsw_sp_ipip_rem_addr_unset_gre4, 363 }; 364 365 static struct mlxsw_sp_ipip_parms 366 mlxsw_sp1_ipip_netdev_parms_init_gre6(const struct net_device *ol_dev) 367 { 368 struct mlxsw_sp_ipip_parms parms = {0}; 369 370 WARN_ON_ONCE(1); 371 return parms; 372 } 373 374 static int 375 mlxsw_sp1_ipip_nexthop_update_gre6(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 376 struct mlxsw_sp_ipip_entry *ipip_entry, 377 bool force, char *ratr_pl) 378 { 379 WARN_ON_ONCE(1); 380 return -EINVAL; 381 } 382 383 static int 384 mlxsw_sp1_ipip_decap_config_gre6(struct mlxsw_sp *mlxsw_sp, 385 struct mlxsw_sp_ipip_entry *ipip_entry, 386 u32 tunnel_index) 387 { 388 WARN_ON_ONCE(1); 389 return -EINVAL; 390 } 391 392 static bool mlxsw_sp1_ipip_can_offload_gre6(const struct mlxsw_sp *mlxsw_sp, 393 const struct net_device *ol_dev) 394 { 395 return false; 396 } 397 398 static struct mlxsw_sp_rif_ipip_lb_config 399 mlxsw_sp1_ipip_ol_loopback_config_gre6(struct mlxsw_sp *mlxsw_sp, 400 const struct net_device *ol_dev) 401 { 402 struct mlxsw_sp_rif_ipip_lb_config config = {0}; 403 404 WARN_ON_ONCE(1); 405 return config; 406 } 407 408 static int 409 mlxsw_sp1_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp, 410 struct mlxsw_sp_ipip_entry *ipip_entry, 411 struct netlink_ext_ack *extack) 412 { 413 WARN_ON_ONCE(1); 414 return -EINVAL; 415 } 416 417 static int 418 mlxsw_sp1_ipip_rem_addr_set_gre6(struct mlxsw_sp *mlxsw_sp, 419 struct mlxsw_sp_ipip_entry *ipip_entry) 420 { 421 WARN_ON_ONCE(1); 422 return -EINVAL; 423 } 424 425 static void 426 mlxsw_sp1_ipip_rem_addr_unset_gre6(struct mlxsw_sp *mlxsw_sp, 427 const struct mlxsw_sp_ipip_entry *ipip_entry) 428 { 429 WARN_ON_ONCE(1); 430 } 431 432 static const struct mlxsw_sp_ipip_ops mlxsw_sp1_ipip_gre6_ops = { 433 .dev_type = ARPHRD_IP6GRE, 434 .ul_proto = MLXSW_SP_L3_PROTO_IPV6, 435 .inc_parsing_depth = true, 436 .parms_init = mlxsw_sp1_ipip_netdev_parms_init_gre6, 437 .nexthop_update = mlxsw_sp1_ipip_nexthop_update_gre6, 438 .decap_config = mlxsw_sp1_ipip_decap_config_gre6, 439 .can_offload = mlxsw_sp1_ipip_can_offload_gre6, 440 .ol_loopback_config = mlxsw_sp1_ipip_ol_loopback_config_gre6, 441 .ol_netdev_change = mlxsw_sp1_ipip_ol_netdev_change_gre6, 442 .rem_ip_addr_set = mlxsw_sp1_ipip_rem_addr_set_gre6, 443 .rem_ip_addr_unset = mlxsw_sp1_ipip_rem_addr_unset_gre6, 444 }; 445 446 const struct mlxsw_sp_ipip_ops *mlxsw_sp1_ipip_ops_arr[] = { 447 [MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops, 448 [MLXSW_SP_IPIP_TYPE_GRE6] = &mlxsw_sp1_ipip_gre6_ops, 449 }; 450 451 static struct mlxsw_sp_ipip_parms 452 mlxsw_sp2_ipip_netdev_parms_init_gre6(const struct net_device *ol_dev) 453 { 454 struct __ip6_tnl_parm parms = mlxsw_sp_ipip_netdev_parms6(ol_dev); 455 456 return (struct mlxsw_sp_ipip_parms) { 457 .proto = MLXSW_SP_L3_PROTO_IPV6, 458 .saddr = mlxsw_sp_ipip_parms6_saddr(&parms), 459 .daddr = mlxsw_sp_ipip_parms6_daddr(&parms), 460 .link = parms.link, 461 .ikey = mlxsw_sp_ipip_parms6_ikey(&parms), 462 .okey = mlxsw_sp_ipip_parms6_okey(&parms), 463 }; 464 } 465 466 static int 467 mlxsw_sp2_ipip_nexthop_update_gre6(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 468 struct mlxsw_sp_ipip_entry *ipip_entry, 469 bool force, char *ratr_pl) 470 { 471 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb); 472 enum mlxsw_reg_ratr_op op; 473 474 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY : 475 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY; 476 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_IPIP, 477 adj_index, rif_index); 478 mlxsw_reg_ratr_ipip6_entry_pack(ratr_pl, 479 ipip_entry->dip_kvdl_index); 480 481 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl); 482 } 483 484 static int 485 mlxsw_sp2_ipip_decap_config_gre6(struct mlxsw_sp *mlxsw_sp, 486 struct mlxsw_sp_ipip_entry *ipip_entry, 487 u32 tunnel_index) 488 { 489 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb); 490 u16 ul_rif_id = mlxsw_sp_ipip_lb_ul_rif_id(ipip_entry->ol_lb); 491 char rtdp_pl[MLXSW_REG_RTDP_LEN]; 492 struct __ip6_tnl_parm parms; 493 unsigned int type_check; 494 bool has_ikey; 495 u32 ikey; 496 497 parms = mlxsw_sp_ipip_netdev_parms6(ipip_entry->ol_dev); 498 has_ikey = mlxsw_sp_ipip_parms6_has_ikey(&parms); 499 ikey = mlxsw_sp_ipip_parms6_ikey(&parms); 500 501 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index); 502 mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_id); 503 504 type_check = has_ikey ? 505 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY : 506 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE; 507 508 /* Linux demuxes tunnels based on packet SIP (which must match tunnel 509 * remote IP). Thus configure decap so that it filters out packets that 510 * are not IPv6 or have the wrong SIP. IPIP_DECAP_ERROR trap is 511 * generated for packets that fail this criterion. Linux then handles 512 * such packets in slow path and generates ICMP destination unreachable. 513 */ 514 mlxsw_reg_rtdp_ipip6_pack(rtdp_pl, rif_index, 515 MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV6, 516 type_check, has_ikey, 517 ipip_entry->dip_kvdl_index, ikey); 518 519 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl); 520 } 521 522 static bool mlxsw_sp2_ipip_can_offload_gre6(const struct mlxsw_sp *mlxsw_sp, 523 const struct net_device *ol_dev) 524 { 525 struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(ol_dev); 526 bool inherit_tos = tparm.flags & IP6_TNL_F_USE_ORIG_TCLASS; 527 bool inherit_ttl = tparm.hop_limit == 0; 528 __be16 okflags = TUNNEL_KEY; /* We can't offload any other features. */ 529 530 return (tparm.i_flags & ~okflags) == 0 && 531 (tparm.o_flags & ~okflags) == 0 && 532 inherit_ttl && inherit_tos && 533 mlxsw_sp_ipip_tunnel_complete(MLXSW_SP_L3_PROTO_IPV6, ol_dev); 534 } 535 536 static struct mlxsw_sp_rif_ipip_lb_config 537 mlxsw_sp2_ipip_ol_loopback_config_gre6(struct mlxsw_sp *mlxsw_sp, 538 const struct net_device *ol_dev) 539 { 540 struct __ip6_tnl_parm parms = mlxsw_sp_ipip_netdev_parms6(ol_dev); 541 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; 542 543 lb_ipipt = mlxsw_sp_ipip_parms6_has_okey(&parms) ? 544 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP : 545 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP; 546 return (struct mlxsw_sp_rif_ipip_lb_config){ 547 .lb_ipipt = lb_ipipt, 548 .okey = mlxsw_sp_ipip_parms6_okey(&parms), 549 .ul_protocol = MLXSW_SP_L3_PROTO_IPV6, 550 .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV6, 551 ol_dev), 552 }; 553 } 554 555 static int 556 mlxsw_sp2_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp, 557 struct mlxsw_sp_ipip_entry *ipip_entry, 558 struct netlink_ext_ack *extack) 559 { 560 struct mlxsw_sp_ipip_parms new_parms; 561 562 new_parms = mlxsw_sp2_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev); 563 return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry, 564 &new_parms, extack); 565 } 566 567 static int 568 mlxsw_sp2_ipip_rem_addr_set_gre6(struct mlxsw_sp *mlxsw_sp, 569 struct mlxsw_sp_ipip_entry *ipip_entry) 570 { 571 return mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp, 572 &ipip_entry->parms.daddr.addr6, 573 &ipip_entry->dip_kvdl_index); 574 } 575 576 static void 577 mlxsw_sp2_ipip_rem_addr_unset_gre6(struct mlxsw_sp *mlxsw_sp, 578 const struct mlxsw_sp_ipip_entry *ipip_entry) 579 { 580 mlxsw_sp_ipv6_addr_put(mlxsw_sp, &ipip_entry->parms.daddr.addr6); 581 } 582 583 static const struct mlxsw_sp_ipip_ops mlxsw_sp2_ipip_gre6_ops = { 584 .dev_type = ARPHRD_IP6GRE, 585 .ul_proto = MLXSW_SP_L3_PROTO_IPV6, 586 .inc_parsing_depth = true, 587 .parms_init = mlxsw_sp2_ipip_netdev_parms_init_gre6, 588 .nexthop_update = mlxsw_sp2_ipip_nexthop_update_gre6, 589 .decap_config = mlxsw_sp2_ipip_decap_config_gre6, 590 .can_offload = mlxsw_sp2_ipip_can_offload_gre6, 591 .ol_loopback_config = mlxsw_sp2_ipip_ol_loopback_config_gre6, 592 .ol_netdev_change = mlxsw_sp2_ipip_ol_netdev_change_gre6, 593 .rem_ip_addr_set = mlxsw_sp2_ipip_rem_addr_set_gre6, 594 .rem_ip_addr_unset = mlxsw_sp2_ipip_rem_addr_unset_gre6, 595 }; 596 597 const struct mlxsw_sp_ipip_ops *mlxsw_sp2_ipip_ops_arr[] = { 598 [MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops, 599 [MLXSW_SP_IPIP_TYPE_GRE6] = &mlxsw_sp2_ipip_gre6_ops, 600 }; 601 602 static int mlxsw_sp_ipip_ecn_encap_init_one(struct mlxsw_sp *mlxsw_sp, 603 u8 inner_ecn, u8 outer_ecn) 604 { 605 char tieem_pl[MLXSW_REG_TIEEM_LEN]; 606 607 mlxsw_reg_tieem_pack(tieem_pl, inner_ecn, outer_ecn); 608 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tieem), tieem_pl); 609 } 610 611 int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp) 612 { 613 int i; 614 615 /* Iterate over inner ECN values */ 616 for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) { 617 u8 outer_ecn = INET_ECN_encapsulate(0, i); 618 int err; 619 620 err = mlxsw_sp_ipip_ecn_encap_init_one(mlxsw_sp, i, outer_ecn); 621 if (err) 622 return err; 623 } 624 625 return 0; 626 } 627 628 static int mlxsw_sp_ipip_ecn_decap_init_one(struct mlxsw_sp *mlxsw_sp, 629 u8 inner_ecn, u8 outer_ecn) 630 { 631 char tidem_pl[MLXSW_REG_TIDEM_LEN]; 632 u8 new_inner_ecn; 633 bool trap_en; 634 635 new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn, 636 &trap_en); 637 mlxsw_reg_tidem_pack(tidem_pl, outer_ecn, inner_ecn, new_inner_ecn, 638 trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0); 639 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tidem), tidem_pl); 640 } 641 642 int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp) 643 { 644 int i, j, err; 645 646 /* Iterate over inner ECN values */ 647 for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) { 648 /* Iterate over outer ECN values */ 649 for (j = INET_ECN_NOT_ECT; j <= INET_ECN_CE; j++) { 650 err = mlxsw_sp_ipip_ecn_decap_init_one(mlxsw_sp, i, j); 651 if (err) 652 return err; 653 } 654 } 655 656 return 0; 657 } 658 659 struct net_device * 660 mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev) 661 { 662 struct net *net = dev_net(ol_dev); 663 struct ip_tunnel *tun4; 664 struct ip6_tnl *tun6; 665 666 switch (ol_dev->type) { 667 case ARPHRD_IPGRE: 668 tun4 = netdev_priv(ol_dev); 669 return dev_get_by_index_rcu(net, tun4->parms.link); 670 case ARPHRD_IP6GRE: 671 tun6 = netdev_priv(ol_dev); 672 return dev_get_by_index_rcu(net, tun6->parms.link); 673 default: 674 return NULL; 675 } 676 } 677