0001
0002
0003
0004 #include <net/ip_tunnels.h>
0005 #include <net/ip6_tunnel.h>
0006 #include <net/inet_ecn.h>
0007
0008 #include "spectrum_ipip.h"
0009 #include "reg.h"
0010
0011 struct ip_tunnel_parm
0012 mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev)
0013 {
0014 struct ip_tunnel *tun = netdev_priv(ol_dev);
0015
0016 return tun->parms;
0017 }
0018
0019 struct __ip6_tnl_parm
0020 mlxsw_sp_ipip_netdev_parms6(const struct net_device *ol_dev)
0021 {
0022 struct ip6_tnl *tun = netdev_priv(ol_dev);
0023
0024 return tun->parms;
0025 }
0026
0027 static bool mlxsw_sp_ipip_parms4_has_ikey(const struct ip_tunnel_parm *parms)
0028 {
0029 return !!(parms->i_flags & TUNNEL_KEY);
0030 }
0031
0032 static bool mlxsw_sp_ipip_parms6_has_ikey(const struct __ip6_tnl_parm *parms)
0033 {
0034 return !!(parms->i_flags & TUNNEL_KEY);
0035 }
0036
0037 static bool mlxsw_sp_ipip_parms4_has_okey(const struct ip_tunnel_parm *parms)
0038 {
0039 return !!(parms->o_flags & TUNNEL_KEY);
0040 }
0041
0042 static bool mlxsw_sp_ipip_parms6_has_okey(const struct __ip6_tnl_parm *parms)
0043 {
0044 return !!(parms->o_flags & TUNNEL_KEY);
0045 }
0046
0047 static u32 mlxsw_sp_ipip_parms4_ikey(const struct ip_tunnel_parm *parms)
0048 {
0049 return mlxsw_sp_ipip_parms4_has_ikey(parms) ?
0050 be32_to_cpu(parms->i_key) : 0;
0051 }
0052
0053 static u32 mlxsw_sp_ipip_parms6_ikey(const struct __ip6_tnl_parm *parms)
0054 {
0055 return mlxsw_sp_ipip_parms6_has_ikey(parms) ?
0056 be32_to_cpu(parms->i_key) : 0;
0057 }
0058
0059 static u32 mlxsw_sp_ipip_parms4_okey(const struct ip_tunnel_parm *parms)
0060 {
0061 return mlxsw_sp_ipip_parms4_has_okey(parms) ?
0062 be32_to_cpu(parms->o_key) : 0;
0063 }
0064
0065 static u32 mlxsw_sp_ipip_parms6_okey(const struct __ip6_tnl_parm *parms)
0066 {
0067 return mlxsw_sp_ipip_parms6_has_okey(parms) ?
0068 be32_to_cpu(parms->o_key) : 0;
0069 }
0070
0071 static union mlxsw_sp_l3addr
0072 mlxsw_sp_ipip_parms4_saddr(const struct ip_tunnel_parm *parms)
0073 {
0074 return (union mlxsw_sp_l3addr) { .addr4 = parms->iph.saddr };
0075 }
0076
0077 static union mlxsw_sp_l3addr
0078 mlxsw_sp_ipip_parms6_saddr(const struct __ip6_tnl_parm *parms)
0079 {
0080 return (union mlxsw_sp_l3addr) { .addr6 = parms->laddr };
0081 }
0082
0083 static union mlxsw_sp_l3addr
0084 mlxsw_sp_ipip_parms4_daddr(const struct ip_tunnel_parm *parms)
0085 {
0086 return (union mlxsw_sp_l3addr) { .addr4 = parms->iph.daddr };
0087 }
0088
0089 static union mlxsw_sp_l3addr
0090 mlxsw_sp_ipip_parms6_daddr(const struct __ip6_tnl_parm *parms)
0091 {
0092 return (union mlxsw_sp_l3addr) { .addr6 = parms->raddr };
0093 }
0094
0095 union mlxsw_sp_l3addr
0096 mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
0097 const struct net_device *ol_dev)
0098 {
0099 struct ip_tunnel_parm parms4;
0100 struct __ip6_tnl_parm parms6;
0101
0102 switch (proto) {
0103 case MLXSW_SP_L3_PROTO_IPV4:
0104 parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
0105 return mlxsw_sp_ipip_parms4_saddr(&parms4);
0106 case MLXSW_SP_L3_PROTO_IPV6:
0107 parms6 = mlxsw_sp_ipip_netdev_parms6(ol_dev);
0108 return mlxsw_sp_ipip_parms6_saddr(&parms6);
0109 }
0110
0111 WARN_ON(1);
0112 return (union mlxsw_sp_l3addr) {0};
0113 }
0114
0115 static __be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev)
0116 {
0117
0118 struct ip_tunnel_parm parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
0119
0120 return mlxsw_sp_ipip_parms4_daddr(&parms4).addr4;
0121 }
0122
0123 static union mlxsw_sp_l3addr
0124 mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto,
0125 const struct net_device *ol_dev)
0126 {
0127 struct ip_tunnel_parm parms4;
0128 struct __ip6_tnl_parm parms6;
0129
0130 switch (proto) {
0131 case MLXSW_SP_L3_PROTO_IPV4:
0132 parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
0133 return mlxsw_sp_ipip_parms4_daddr(&parms4);
0134 case MLXSW_SP_L3_PROTO_IPV6:
0135 parms6 = mlxsw_sp_ipip_netdev_parms6(ol_dev);
0136 return mlxsw_sp_ipip_parms6_daddr(&parms6);
0137 }
0138
0139 WARN_ON(1);
0140 return (union mlxsw_sp_l3addr) {0};
0141 }
0142
0143 bool mlxsw_sp_l3addr_is_zero(union mlxsw_sp_l3addr addr)
0144 {
0145 union mlxsw_sp_l3addr naddr = {0};
0146
0147 return !memcmp(&addr, &naddr, sizeof(naddr));
0148 }
0149
0150 static struct mlxsw_sp_ipip_parms
0151 mlxsw_sp_ipip_netdev_parms_init_gre4(const struct net_device *ol_dev)
0152 {
0153 struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);
0154
0155 return (struct mlxsw_sp_ipip_parms) {
0156 .proto = MLXSW_SP_L3_PROTO_IPV4,
0157 .saddr = mlxsw_sp_ipip_parms4_saddr(&parms),
0158 .daddr = mlxsw_sp_ipip_parms4_daddr(&parms),
0159 .link = parms.link,
0160 .ikey = mlxsw_sp_ipip_parms4_ikey(&parms),
0161 .okey = mlxsw_sp_ipip_parms4_okey(&parms),
0162 };
0163 }
0164
0165 static int
0166 mlxsw_sp_ipip_nexthop_update_gre4(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
0167 struct mlxsw_sp_ipip_entry *ipip_entry,
0168 bool force, char *ratr_pl)
0169 {
0170 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
0171 __be32 daddr4 = mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev);
0172 enum mlxsw_reg_ratr_op op;
0173
0174 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :
0175 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;
0176 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_IPIP,
0177 adj_index, rif_index);
0178 mlxsw_reg_ratr_ipip4_entry_pack(ratr_pl, be32_to_cpu(daddr4));
0179
0180 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
0181 }
0182
0183 static int
0184 mlxsw_sp_ipip_decap_config_gre4(struct mlxsw_sp *mlxsw_sp,
0185 struct mlxsw_sp_ipip_entry *ipip_entry,
0186 u32 tunnel_index)
0187 {
0188 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
0189 u16 ul_rif_id = mlxsw_sp_ipip_lb_ul_rif_id(ipip_entry->ol_lb);
0190 char rtdp_pl[MLXSW_REG_RTDP_LEN];
0191 struct ip_tunnel_parm parms;
0192 unsigned int type_check;
0193 bool has_ikey;
0194 u32 daddr4;
0195 u32 ikey;
0196
0197 parms = mlxsw_sp_ipip_netdev_parms4(ipip_entry->ol_dev);
0198 has_ikey = mlxsw_sp_ipip_parms4_has_ikey(&parms);
0199 ikey = mlxsw_sp_ipip_parms4_ikey(&parms);
0200
0201 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index);
0202 mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_id);
0203
0204 type_check = has_ikey ?
0205 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY :
0206 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE;
0207
0208
0209
0210
0211
0212
0213
0214 daddr4 = be32_to_cpu(mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev));
0215 mlxsw_reg_rtdp_ipip4_pack(rtdp_pl, rif_index,
0216 MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV4,
0217 type_check, has_ikey, daddr4, ikey);
0218
0219 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
0220 }
0221
0222 static bool mlxsw_sp_ipip_tunnel_complete(enum mlxsw_sp_l3proto proto,
0223 const struct net_device *ol_dev)
0224 {
0225 union mlxsw_sp_l3addr saddr = mlxsw_sp_ipip_netdev_saddr(proto, ol_dev);
0226 union mlxsw_sp_l3addr daddr = mlxsw_sp_ipip_netdev_daddr(proto, ol_dev);
0227
0228
0229
0230
0231
0232
0233 return !mlxsw_sp_l3addr_is_zero(saddr) &&
0234 !mlxsw_sp_l3addr_is_zero(daddr);
0235 }
0236
0237 static bool mlxsw_sp_ipip_can_offload_gre4(const struct mlxsw_sp *mlxsw_sp,
0238 const struct net_device *ol_dev)
0239 {
0240 struct ip_tunnel *tunnel = netdev_priv(ol_dev);
0241 __be16 okflags = TUNNEL_KEY;
0242 bool inherit_ttl = tunnel->parms.iph.ttl == 0;
0243 bool inherit_tos = tunnel->parms.iph.tos & 0x1;
0244
0245 return (tunnel->parms.i_flags & ~okflags) == 0 &&
0246 (tunnel->parms.o_flags & ~okflags) == 0 &&
0247 inherit_ttl && inherit_tos &&
0248 mlxsw_sp_ipip_tunnel_complete(MLXSW_SP_L3_PROTO_IPV4, ol_dev);
0249 }
0250
0251 static struct mlxsw_sp_rif_ipip_lb_config
0252 mlxsw_sp_ipip_ol_loopback_config_gre4(struct mlxsw_sp *mlxsw_sp,
0253 const struct net_device *ol_dev)
0254 {
0255 struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);
0256 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
0257
0258 lb_ipipt = mlxsw_sp_ipip_parms4_has_okey(&parms) ?
0259 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP :
0260 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP;
0261 return (struct mlxsw_sp_rif_ipip_lb_config){
0262 .lb_ipipt = lb_ipipt,
0263 .okey = mlxsw_sp_ipip_parms4_okey(&parms),
0264 .ul_protocol = MLXSW_SP_L3_PROTO_IPV4,
0265 .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV4,
0266 ol_dev),
0267 };
0268 }
0269
0270 static int
0271 mlxsw_sp_ipip_ol_netdev_change_gre(struct mlxsw_sp *mlxsw_sp,
0272 struct mlxsw_sp_ipip_entry *ipip_entry,
0273 const struct mlxsw_sp_ipip_parms *new_parms,
0274 struct netlink_ext_ack *extack)
0275 {
0276 const struct mlxsw_sp_ipip_parms *old_parms = &ipip_entry->parms;
0277 bool update_tunnel = false;
0278 bool update_decap = false;
0279 bool update_nhs = false;
0280 int err = 0;
0281
0282 if (!mlxsw_sp_l3addr_eq(&new_parms->saddr, &old_parms->saddr)) {
0283 u16 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);
0284
0285
0286
0287
0288 if (mlxsw_sp_ipip_demote_tunnel_by_saddr(mlxsw_sp,
0289 new_parms->proto,
0290 new_parms->saddr,
0291 ul_tb_id,
0292 ipip_entry)) {
0293 mlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry);
0294 return 0;
0295 }
0296
0297 update_tunnel = true;
0298 } else if (old_parms->okey != new_parms->okey ||
0299 old_parms->link != new_parms->link) {
0300 update_tunnel = true;
0301 } else if (!mlxsw_sp_l3addr_eq(&new_parms->daddr, &old_parms->daddr)) {
0302 update_nhs = true;
0303 } else if (old_parms->ikey != new_parms->ikey) {
0304 update_decap = true;
0305 }
0306
0307 if (update_tunnel)
0308 err = __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
0309 true, true, true,
0310 extack);
0311 else if (update_nhs)
0312 err = __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
0313 false, false, true,
0314 extack);
0315 else if (update_decap)
0316 err = __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
0317 false, false, false,
0318 extack);
0319 if (err)
0320 return err;
0321
0322 ipip_entry->parms = *new_parms;
0323 return 0;
0324 }
0325
0326 static int
0327 mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp,
0328 struct mlxsw_sp_ipip_entry *ipip_entry,
0329 struct netlink_ext_ack *extack)
0330 {
0331 struct mlxsw_sp_ipip_parms new_parms;
0332
0333 new_parms = mlxsw_sp_ipip_netdev_parms_init_gre4(ipip_entry->ol_dev);
0334 return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
0335 &new_parms, extack);
0336 }
0337
0338 static int
0339 mlxsw_sp_ipip_rem_addr_set_gre4(struct mlxsw_sp *mlxsw_sp,
0340 struct mlxsw_sp_ipip_entry *ipip_entry)
0341 {
0342 return 0;
0343 }
0344
0345 static void
0346 mlxsw_sp_ipip_rem_addr_unset_gre4(struct mlxsw_sp *mlxsw_sp,
0347 const struct mlxsw_sp_ipip_entry *ipip_entry)
0348 {
0349 }
0350
0351 static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = {
0352 .dev_type = ARPHRD_IPGRE,
0353 .ul_proto = MLXSW_SP_L3_PROTO_IPV4,
0354 .inc_parsing_depth = false,
0355 .parms_init = mlxsw_sp_ipip_netdev_parms_init_gre4,
0356 .nexthop_update = mlxsw_sp_ipip_nexthop_update_gre4,
0357 .decap_config = mlxsw_sp_ipip_decap_config_gre4,
0358 .can_offload = mlxsw_sp_ipip_can_offload_gre4,
0359 .ol_loopback_config = mlxsw_sp_ipip_ol_loopback_config_gre4,
0360 .ol_netdev_change = mlxsw_sp_ipip_ol_netdev_change_gre4,
0361 .rem_ip_addr_set = mlxsw_sp_ipip_rem_addr_set_gre4,
0362 .rem_ip_addr_unset = mlxsw_sp_ipip_rem_addr_unset_gre4,
0363 };
0364
0365 static struct mlxsw_sp_ipip_parms
0366 mlxsw_sp1_ipip_netdev_parms_init_gre6(const struct net_device *ol_dev)
0367 {
0368 struct mlxsw_sp_ipip_parms parms = {0};
0369
0370 WARN_ON_ONCE(1);
0371 return parms;
0372 }
0373
0374 static int
0375 mlxsw_sp1_ipip_nexthop_update_gre6(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
0376 struct mlxsw_sp_ipip_entry *ipip_entry,
0377 bool force, char *ratr_pl)
0378 {
0379 WARN_ON_ONCE(1);
0380 return -EINVAL;
0381 }
0382
0383 static int
0384 mlxsw_sp1_ipip_decap_config_gre6(struct mlxsw_sp *mlxsw_sp,
0385 struct mlxsw_sp_ipip_entry *ipip_entry,
0386 u32 tunnel_index)
0387 {
0388 WARN_ON_ONCE(1);
0389 return -EINVAL;
0390 }
0391
0392 static bool mlxsw_sp1_ipip_can_offload_gre6(const struct mlxsw_sp *mlxsw_sp,
0393 const struct net_device *ol_dev)
0394 {
0395 return false;
0396 }
0397
0398 static struct mlxsw_sp_rif_ipip_lb_config
0399 mlxsw_sp1_ipip_ol_loopback_config_gre6(struct mlxsw_sp *mlxsw_sp,
0400 const struct net_device *ol_dev)
0401 {
0402 struct mlxsw_sp_rif_ipip_lb_config config = {0};
0403
0404 WARN_ON_ONCE(1);
0405 return config;
0406 }
0407
0408 static int
0409 mlxsw_sp1_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp,
0410 struct mlxsw_sp_ipip_entry *ipip_entry,
0411 struct netlink_ext_ack *extack)
0412 {
0413 WARN_ON_ONCE(1);
0414 return -EINVAL;
0415 }
0416
0417 static int
0418 mlxsw_sp1_ipip_rem_addr_set_gre6(struct mlxsw_sp *mlxsw_sp,
0419 struct mlxsw_sp_ipip_entry *ipip_entry)
0420 {
0421 WARN_ON_ONCE(1);
0422 return -EINVAL;
0423 }
0424
0425 static void
0426 mlxsw_sp1_ipip_rem_addr_unset_gre6(struct mlxsw_sp *mlxsw_sp,
0427 const struct mlxsw_sp_ipip_entry *ipip_entry)
0428 {
0429 WARN_ON_ONCE(1);
0430 }
0431
0432 static const struct mlxsw_sp_ipip_ops mlxsw_sp1_ipip_gre6_ops = {
0433 .dev_type = ARPHRD_IP6GRE,
0434 .ul_proto = MLXSW_SP_L3_PROTO_IPV6,
0435 .inc_parsing_depth = true,
0436 .parms_init = mlxsw_sp1_ipip_netdev_parms_init_gre6,
0437 .nexthop_update = mlxsw_sp1_ipip_nexthop_update_gre6,
0438 .decap_config = mlxsw_sp1_ipip_decap_config_gre6,
0439 .can_offload = mlxsw_sp1_ipip_can_offload_gre6,
0440 .ol_loopback_config = mlxsw_sp1_ipip_ol_loopback_config_gre6,
0441 .ol_netdev_change = mlxsw_sp1_ipip_ol_netdev_change_gre6,
0442 .rem_ip_addr_set = mlxsw_sp1_ipip_rem_addr_set_gre6,
0443 .rem_ip_addr_unset = mlxsw_sp1_ipip_rem_addr_unset_gre6,
0444 };
0445
0446 const struct mlxsw_sp_ipip_ops *mlxsw_sp1_ipip_ops_arr[] = {
0447 [MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops,
0448 [MLXSW_SP_IPIP_TYPE_GRE6] = &mlxsw_sp1_ipip_gre6_ops,
0449 };
0450
0451 static struct mlxsw_sp_ipip_parms
0452 mlxsw_sp2_ipip_netdev_parms_init_gre6(const struct net_device *ol_dev)
0453 {
0454 struct __ip6_tnl_parm parms = mlxsw_sp_ipip_netdev_parms6(ol_dev);
0455
0456 return (struct mlxsw_sp_ipip_parms) {
0457 .proto = MLXSW_SP_L3_PROTO_IPV6,
0458 .saddr = mlxsw_sp_ipip_parms6_saddr(&parms),
0459 .daddr = mlxsw_sp_ipip_parms6_daddr(&parms),
0460 .link = parms.link,
0461 .ikey = mlxsw_sp_ipip_parms6_ikey(&parms),
0462 .okey = mlxsw_sp_ipip_parms6_okey(&parms),
0463 };
0464 }
0465
0466 static int
0467 mlxsw_sp2_ipip_nexthop_update_gre6(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
0468 struct mlxsw_sp_ipip_entry *ipip_entry,
0469 bool force, char *ratr_pl)
0470 {
0471 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
0472 enum mlxsw_reg_ratr_op op;
0473
0474 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :
0475 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;
0476 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_IPIP,
0477 adj_index, rif_index);
0478 mlxsw_reg_ratr_ipip6_entry_pack(ratr_pl,
0479 ipip_entry->dip_kvdl_index);
0480
0481 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
0482 }
0483
0484 static int
0485 mlxsw_sp2_ipip_decap_config_gre6(struct mlxsw_sp *mlxsw_sp,
0486 struct mlxsw_sp_ipip_entry *ipip_entry,
0487 u32 tunnel_index)
0488 {
0489 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
0490 u16 ul_rif_id = mlxsw_sp_ipip_lb_ul_rif_id(ipip_entry->ol_lb);
0491 char rtdp_pl[MLXSW_REG_RTDP_LEN];
0492 struct __ip6_tnl_parm parms;
0493 unsigned int type_check;
0494 bool has_ikey;
0495 u32 ikey;
0496
0497 parms = mlxsw_sp_ipip_netdev_parms6(ipip_entry->ol_dev);
0498 has_ikey = mlxsw_sp_ipip_parms6_has_ikey(&parms);
0499 ikey = mlxsw_sp_ipip_parms6_ikey(&parms);
0500
0501 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index);
0502 mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_id);
0503
0504 type_check = has_ikey ?
0505 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY :
0506 MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE;
0507
0508
0509
0510
0511
0512
0513
0514 mlxsw_reg_rtdp_ipip6_pack(rtdp_pl, rif_index,
0515 MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV6,
0516 type_check, has_ikey,
0517 ipip_entry->dip_kvdl_index, ikey);
0518
0519 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
0520 }
0521
0522 static bool mlxsw_sp2_ipip_can_offload_gre6(const struct mlxsw_sp *mlxsw_sp,
0523 const struct net_device *ol_dev)
0524 {
0525 struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(ol_dev);
0526 bool inherit_tos = tparm.flags & IP6_TNL_F_USE_ORIG_TCLASS;
0527 bool inherit_ttl = tparm.hop_limit == 0;
0528 __be16 okflags = TUNNEL_KEY;
0529
0530 return (tparm.i_flags & ~okflags) == 0 &&
0531 (tparm.o_flags & ~okflags) == 0 &&
0532 inherit_ttl && inherit_tos &&
0533 mlxsw_sp_ipip_tunnel_complete(MLXSW_SP_L3_PROTO_IPV6, ol_dev);
0534 }
0535
0536 static struct mlxsw_sp_rif_ipip_lb_config
0537 mlxsw_sp2_ipip_ol_loopback_config_gre6(struct mlxsw_sp *mlxsw_sp,
0538 const struct net_device *ol_dev)
0539 {
0540 struct __ip6_tnl_parm parms = mlxsw_sp_ipip_netdev_parms6(ol_dev);
0541 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
0542
0543 lb_ipipt = mlxsw_sp_ipip_parms6_has_okey(&parms) ?
0544 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP :
0545 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP;
0546 return (struct mlxsw_sp_rif_ipip_lb_config){
0547 .lb_ipipt = lb_ipipt,
0548 .okey = mlxsw_sp_ipip_parms6_okey(&parms),
0549 .ul_protocol = MLXSW_SP_L3_PROTO_IPV6,
0550 .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV6,
0551 ol_dev),
0552 };
0553 }
0554
0555 static int
0556 mlxsw_sp2_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp,
0557 struct mlxsw_sp_ipip_entry *ipip_entry,
0558 struct netlink_ext_ack *extack)
0559 {
0560 struct mlxsw_sp_ipip_parms new_parms;
0561
0562 new_parms = mlxsw_sp2_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev);
0563 return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
0564 &new_parms, extack);
0565 }
0566
0567 static int
0568 mlxsw_sp2_ipip_rem_addr_set_gre6(struct mlxsw_sp *mlxsw_sp,
0569 struct mlxsw_sp_ipip_entry *ipip_entry)
0570 {
0571 return mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp,
0572 &ipip_entry->parms.daddr.addr6,
0573 &ipip_entry->dip_kvdl_index);
0574 }
0575
0576 static void
0577 mlxsw_sp2_ipip_rem_addr_unset_gre6(struct mlxsw_sp *mlxsw_sp,
0578 const struct mlxsw_sp_ipip_entry *ipip_entry)
0579 {
0580 mlxsw_sp_ipv6_addr_put(mlxsw_sp, &ipip_entry->parms.daddr.addr6);
0581 }
0582
0583 static const struct mlxsw_sp_ipip_ops mlxsw_sp2_ipip_gre6_ops = {
0584 .dev_type = ARPHRD_IP6GRE,
0585 .ul_proto = MLXSW_SP_L3_PROTO_IPV6,
0586 .inc_parsing_depth = true,
0587 .parms_init = mlxsw_sp2_ipip_netdev_parms_init_gre6,
0588 .nexthop_update = mlxsw_sp2_ipip_nexthop_update_gre6,
0589 .decap_config = mlxsw_sp2_ipip_decap_config_gre6,
0590 .can_offload = mlxsw_sp2_ipip_can_offload_gre6,
0591 .ol_loopback_config = mlxsw_sp2_ipip_ol_loopback_config_gre6,
0592 .ol_netdev_change = mlxsw_sp2_ipip_ol_netdev_change_gre6,
0593 .rem_ip_addr_set = mlxsw_sp2_ipip_rem_addr_set_gre6,
0594 .rem_ip_addr_unset = mlxsw_sp2_ipip_rem_addr_unset_gre6,
0595 };
0596
0597 const struct mlxsw_sp_ipip_ops *mlxsw_sp2_ipip_ops_arr[] = {
0598 [MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops,
0599 [MLXSW_SP_IPIP_TYPE_GRE6] = &mlxsw_sp2_ipip_gre6_ops,
0600 };
0601
0602 static int mlxsw_sp_ipip_ecn_encap_init_one(struct mlxsw_sp *mlxsw_sp,
0603 u8 inner_ecn, u8 outer_ecn)
0604 {
0605 char tieem_pl[MLXSW_REG_TIEEM_LEN];
0606
0607 mlxsw_reg_tieem_pack(tieem_pl, inner_ecn, outer_ecn);
0608 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tieem), tieem_pl);
0609 }
0610
0611 int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp)
0612 {
0613 int i;
0614
0615
0616 for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) {
0617 u8 outer_ecn = INET_ECN_encapsulate(0, i);
0618 int err;
0619
0620 err = mlxsw_sp_ipip_ecn_encap_init_one(mlxsw_sp, i, outer_ecn);
0621 if (err)
0622 return err;
0623 }
0624
0625 return 0;
0626 }
0627
0628 static int mlxsw_sp_ipip_ecn_decap_init_one(struct mlxsw_sp *mlxsw_sp,
0629 u8 inner_ecn, u8 outer_ecn)
0630 {
0631 char tidem_pl[MLXSW_REG_TIDEM_LEN];
0632 u8 new_inner_ecn;
0633 bool trap_en;
0634
0635 new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn,
0636 &trap_en);
0637 mlxsw_reg_tidem_pack(tidem_pl, outer_ecn, inner_ecn, new_inner_ecn,
0638 trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0);
0639 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tidem), tidem_pl);
0640 }
0641
0642 int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp)
0643 {
0644 int i, j, err;
0645
0646
0647 for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) {
0648
0649 for (j = INET_ECN_NOT_ECT; j <= INET_ECN_CE; j++) {
0650 err = mlxsw_sp_ipip_ecn_decap_init_one(mlxsw_sp, i, j);
0651 if (err)
0652 return err;
0653 }
0654 }
0655
0656 return 0;
0657 }
0658
0659 struct net_device *
0660 mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev)
0661 {
0662 struct net *net = dev_net(ol_dev);
0663 struct ip_tunnel *tun4;
0664 struct ip6_tnl *tun6;
0665
0666 switch (ol_dev->type) {
0667 case ARPHRD_IPGRE:
0668 tun4 = netdev_priv(ol_dev);
0669 return dev_get_by_index_rcu(net, tun4->parms.link);
0670 case ARPHRD_IP6GRE:
0671 tun6 = netdev_priv(ol_dev);
0672 return dev_get_by_index_rcu(net, tun6->parms.link);
0673 default:
0674 return NULL;
0675 }
0676 }