Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit f485da3

Browse files
committed
Merge branch 'mlxsw-dip-sip-mangling'
Ido Schimmel says: ==================== mlxsw: Add SIP and DIP mangling support Danielle says: On Spectrum-2 onwards, it is possible to overwrite SIP and DIP address of an IPv4 or IPv6 packet in the ACL engine. That corresponds to pedit munges of, respectively, ip src and ip dst fields, and likewise for ip6. Offload these munges on the systems where they are supported. Patchset overview: Patch #1: introduces SIP_DIP_ACTION and its fields. Patch #2-#3: adds the new pedit fields, and dispatches on them on Spectrum-2 and above. Patch #4 adds a selftest. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 47c1a9a + 92ad382 commit f485da3

File tree

6 files changed

+394
-9
lines changed

6 files changed

+394
-9
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,83 @@ int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
19571957
}
19581958
EXPORT_SYMBOL(mlxsw_afa_block_append_mcrouter);
19591959

1960+
/* SIP DIP Action
1961+
* --------------
1962+
* The SIP_DIP_ACTION is used for modifying the SIP and DIP fields of the
1963+
* packet, e.g. for NAT. The L3 checksum is updated. Also, if the L4 is TCP or
1964+
* if the L4 is UDP and the checksum field is not zero, then the L4 checksum is
1965+
* updated.
1966+
*/
1967+
1968+
#define MLXSW_AFA_IP_CODE 0x11
1969+
#define MLXSW_AFA_IP_SIZE 2
1970+
1971+
enum mlxsw_afa_ip_s_d {
1972+
/* ip refers to dip */
1973+
MLXSW_AFA_IP_S_D_DIP,
1974+
/* ip refers to sip */
1975+
MLXSW_AFA_IP_S_D_SIP,
1976+
};
1977+
1978+
/* afa_ip_s_d
1979+
* Source or destination.
1980+
*/
1981+
MLXSW_ITEM32(afa, ip, s_d, 0x00, 31, 1);
1982+
1983+
enum mlxsw_afa_ip_m_l {
1984+
/* LSB: ip[63:0] refers to ip[63:0] */
1985+
MLXSW_AFA_IP_M_L_LSB,
1986+
/* MSB: ip[63:0] refers to ip[127:64] */
1987+
MLXSW_AFA_IP_M_L_MSB,
1988+
};
1989+
1990+
/* afa_ip_m_l
1991+
* MSB or LSB.
1992+
*/
1993+
MLXSW_ITEM32(afa, ip, m_l, 0x00, 30, 1);
1994+
1995+
/* afa_ip_ip_63_32
1996+
* Bits [63:32] in the IP address to change to.
1997+
*/
1998+
MLXSW_ITEM32(afa, ip, ip_63_32, 0x08, 0, 32);
1999+
2000+
/* afa_ip_ip_31_0
2001+
* Bits [31:0] in the IP address to change to.
2002+
*/
2003+
MLXSW_ITEM32(afa, ip, ip_31_0, 0x0C, 0, 32);
2004+
2005+
static void mlxsw_afa_ip_pack(char *payload, enum mlxsw_afa_ip_s_d s_d,
2006+
enum mlxsw_afa_ip_m_l m_l, u32 ip_31_0,
2007+
u32 ip_63_32)
2008+
{
2009+
mlxsw_afa_ip_s_d_set(payload, s_d);
2010+
mlxsw_afa_ip_m_l_set(payload, m_l);
2011+
mlxsw_afa_ip_ip_31_0_set(payload, ip_31_0);
2012+
mlxsw_afa_ip_ip_63_32_set(payload, ip_63_32);
2013+
}
2014+
2015+
int mlxsw_afa_block_append_ip(struct mlxsw_afa_block *block, bool is_dip,
2016+
bool is_lsb, u32 val_31_0, u32 val_63_32,
2017+
struct netlink_ext_ack *extack)
2018+
{
2019+
enum mlxsw_afa_ip_s_d s_d = is_dip ? MLXSW_AFA_IP_S_D_DIP :
2020+
MLXSW_AFA_IP_S_D_SIP;
2021+
enum mlxsw_afa_ip_m_l m_l = is_lsb ? MLXSW_AFA_IP_M_L_LSB :
2022+
MLXSW_AFA_IP_M_L_MSB;
2023+
char *act = mlxsw_afa_block_append_action(block,
2024+
MLXSW_AFA_IP_CODE,
2025+
MLXSW_AFA_IP_SIZE);
2026+
2027+
if (IS_ERR(act)) {
2028+
NL_SET_ERR_MSG_MOD(extack, "Cannot append IP action");
2029+
return PTR_ERR(act);
2030+
}
2031+
2032+
mlxsw_afa_ip_pack(act, s_d, m_l, val_31_0, val_63_32);
2033+
return 0;
2034+
}
2035+
EXPORT_SYMBOL(mlxsw_afa_block_append_ip);
2036+
19602037
/* L4 Port Action
19612038
* --------------
19622039
* The L4_PORT_ACTION is used for modifying the sport and dport fields of the packet, e.g. for NAT.

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid,
9292
int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
9393
u16 expected_irif, u16 min_mtu,
9494
bool rmid_valid, u32 kvdl_index);
95+
int mlxsw_afa_block_append_ip(struct mlxsw_afa_block *block, bool is_dip,
96+
bool is_lsb, u32 val_31_0, u32 val_63_32,
97+
struct netlink_ext_ack *extack);
9598
int mlxsw_afa_block_append_l4port(struct mlxsw_afa_block *block, bool is_dport, u16 l4_port,
9699
struct netlink_ext_ack *extack);
97100
int mlxsw_afa_block_append_police(struct mlxsw_afa_block *block,

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,24 @@ int mlxsw_sp1_kvdl_resources_register(struct mlxsw_core *mlxsw_core);
820820
/* spectrum2_kvdl.c */
821821
extern const struct mlxsw_sp_kvdl_ops mlxsw_sp2_kvdl_ops;
822822

823+
enum mlxsw_sp_acl_mangle_field {
824+
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSFIELD,
825+
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSCP,
826+
MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN,
827+
MLXSW_SP_ACL_MANGLE_FIELD_IP_SPORT,
828+
MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT,
829+
MLXSW_SP_ACL_MANGLE_FIELD_IP4_SIP,
830+
MLXSW_SP_ACL_MANGLE_FIELD_IP4_DIP,
831+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_1,
832+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_2,
833+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_3,
834+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_4,
835+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_1,
836+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_2,
837+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_3,
838+
MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_4,
839+
};
840+
823841
struct mlxsw_sp_acl_rule_info {
824842
unsigned int priority;
825843
struct mlxsw_afk_element_values values;
@@ -828,9 +846,14 @@ struct mlxsw_sp_acl_rule_info {
828846
ingress_bind_blocker:1,
829847
egress_bind_blocker:1,
830848
counter_valid:1,
831-
policer_index_valid:1;
849+
policer_index_valid:1,
850+
ipv6_valid:1;
832851
unsigned int counter_index;
833852
u16 policer_index;
853+
struct {
854+
u32 prev_val;
855+
enum mlxsw_sp_acl_mangle_field prev_field;
856+
} ipv6;
834857
};
835858

836859
/* spectrum_flow.c */

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -505,14 +505,6 @@ int mlxsw_sp_acl_rulei_act_priority(struct mlxsw_sp *mlxsw_sp,
505505
extack);
506506
}
507507

508-
enum mlxsw_sp_acl_mangle_field {
509-
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSFIELD,
510-
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSCP,
511-
MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN,
512-
MLXSW_SP_ACL_MANGLE_FIELD_IP_SPORT,
513-
MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT,
514-
};
515-
516508
struct mlxsw_sp_acl_mangle_action {
517509
enum flow_action_mangle_base htype;
518510
/* Offset is u32-aligned. */
@@ -561,6 +553,18 @@ static struct mlxsw_sp_acl_mangle_action mlxsw_sp_acl_mangle_actions[] = {
561553

562554
MLXSW_SP_ACL_MANGLE_ACTION_UDP(0, 0x0000ffff, 16, IP_SPORT),
563555
MLXSW_SP_ACL_MANGLE_ACTION_UDP(0, 0xffff0000, 0, IP_DPORT),
556+
557+
MLXSW_SP_ACL_MANGLE_ACTION_IP4(12, 0x00000000, 0, IP4_SIP),
558+
MLXSW_SP_ACL_MANGLE_ACTION_IP4(16, 0x00000000, 0, IP4_DIP),
559+
560+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(8, 0x00000000, 0, IP6_SIP_1),
561+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(12, 0x00000000, 0, IP6_SIP_2),
562+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(16, 0x00000000, 0, IP6_SIP_3),
563+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(20, 0x00000000, 0, IP6_SIP_4),
564+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(24, 0x00000000, 0, IP6_DIP_1),
565+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(28, 0x00000000, 0, IP6_DIP_2),
566+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(32, 0x00000000, 0, IP6_DIP_3),
567+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(36, 0x00000000, 0, IP6_DIP_4),
564568
};
565569

566570
static int
@@ -599,6 +603,22 @@ static int mlxsw_sp1_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
599603
return err;
600604
}
601605

606+
static int
607+
mlxsw_sp2_acl_rulei_act_mangle_field_ip_odd(struct mlxsw_sp_acl_rule_info *rulei,
608+
enum mlxsw_sp_acl_mangle_field field,
609+
u32 val, struct netlink_ext_ack *extack)
610+
{
611+
if (!rulei->ipv6_valid) {
612+
rulei->ipv6.prev_val = val;
613+
rulei->ipv6_valid = true;
614+
rulei->ipv6.prev_field = field;
615+
return 0;
616+
}
617+
618+
NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field order");
619+
return -EOPNOTSUPP;
620+
}
621+
602622
static int mlxsw_sp2_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
603623
struct mlxsw_sp_acl_rule_info *rulei,
604624
struct mlxsw_sp_acl_mangle_action *mact,
@@ -615,6 +635,61 @@ static int mlxsw_sp2_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
615635
return mlxsw_afa_block_append_l4port(rulei->act_block, false, val, extack);
616636
case MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT:
617637
return mlxsw_afa_block_append_l4port(rulei->act_block, true, val, extack);
638+
/* IPv4 fields */
639+
case MLXSW_SP_ACL_MANGLE_FIELD_IP4_SIP:
640+
return mlxsw_afa_block_append_ip(rulei->act_block, false,
641+
true, val, 0, extack);
642+
case MLXSW_SP_ACL_MANGLE_FIELD_IP4_DIP:
643+
return mlxsw_afa_block_append_ip(rulei->act_block, true,
644+
true, val, 0, extack);
645+
/* IPv6 fields */
646+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_1:
647+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_3:
648+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_1:
649+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_3:
650+
return mlxsw_sp2_acl_rulei_act_mangle_field_ip_odd(rulei,
651+
mact->field,
652+
val, extack);
653+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_2:
654+
if (rulei->ipv6_valid &&
655+
rulei->ipv6.prev_field == MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_1) {
656+
rulei->ipv6_valid = false;
657+
return mlxsw_afa_block_append_ip(rulei->act_block,
658+
false, false, val,
659+
rulei->ipv6.prev_val,
660+
extack);
661+
}
662+
break;
663+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_4:
664+
if (rulei->ipv6_valid &&
665+
rulei->ipv6.prev_field == MLXSW_SP_ACL_MANGLE_FIELD_IP6_SIP_3) {
666+
rulei->ipv6_valid = false;
667+
return mlxsw_afa_block_append_ip(rulei->act_block,
668+
false, true, val,
669+
rulei->ipv6.prev_val,
670+
extack);
671+
}
672+
break;
673+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_2:
674+
if (rulei->ipv6_valid &&
675+
rulei->ipv6.prev_field == MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_1) {
676+
rulei->ipv6_valid = false;
677+
return mlxsw_afa_block_append_ip(rulei->act_block,
678+
true, false, val,
679+
rulei->ipv6.prev_val,
680+
extack);
681+
}
682+
break;
683+
case MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_4:
684+
if (rulei->ipv6_valid &&
685+
rulei->ipv6.prev_field == MLXSW_SP_ACL_MANGLE_FIELD_IP6_DIP_3) {
686+
rulei->ipv6_valid = false;
687+
return mlxsw_afa_block_append_ip(rulei->act_block,
688+
true, true, val,
689+
rulei->ipv6.prev_val,
690+
extack);
691+
}
692+
break;
618693
default:
619694
break;
620695
}

drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
233233
return -EOPNOTSUPP;
234234
}
235235
}
236+
237+
if (rulei->ipv6_valid) {
238+
NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
239+
return -EOPNOTSUPP;
240+
}
241+
236242
return 0;
237243
}
238244

0 commit comments

Comments
 (0)