Commit 63b53b0b authored by Rahul Lakkireddy's avatar Rahul Lakkireddy Committed by David S. Miller

cxgb4: fix endian conversions for L4 ports in filters

The source and destination L4 ports in filter offload need to be
in CPU endian. They will finally be converted to Big Endian after
all operations are done and before giving them to hardware. The
L4 ports for NAT are expected to be passed as a byte stream TCB.
So, treat them as such.

Fixes following sparse warnings in several places:
cxgb4_tc_flower.c:159:33: warning: cast from restricted __be16
cxgb4_tc_flower.c:159:33: warning: incorrect type in argument 1 (different
base types)
cxgb4_tc_flower.c:159:33:    expected unsigned short [usertype] val
cxgb4_tc_flower.c:159:33:    got restricted __be16 [usertype] dst

Fixes: dca4faeb ("cxgb4: Add LE hash collision bug fix path in LLD driver")
Fixes: 62488e4b ("cxgb4: add basic tc flower offload support")
Fixes: 557ccbf9 ("cxgb4: add tc flower support for L3/L4 rewrite")
Signed-off-by: default avatarRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 27f78cb2
...@@ -165,6 +165,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f, ...@@ -165,6 +165,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f,
unsigned int tid, bool dip, bool sip, bool dp, unsigned int tid, bool dip, bool sip, bool dp,
bool sp) bool sp)
{ {
u8 *nat_lp = (u8 *)&f->fs.nat_lport;
u8 *nat_fp = (u8 *)&f->fs.nat_fport;
if (dip) { if (dip) {
if (f->fs.type) { if (f->fs.type) {
set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W, set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W,
...@@ -236,8 +239,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f, ...@@ -236,8 +239,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f,
} }
set_tcb_field(adap, f, tid, TCB_PDU_HDR_LEN_W, WORD_MASK, set_tcb_field(adap, f, tid, TCB_PDU_HDR_LEN_W, WORD_MASK,
(dp ? f->fs.nat_lport : 0) | (dp ? (nat_lp[1] | nat_lp[0] << 8) : 0) |
(sp ? f->fs.nat_fport << 16 : 0), 1); (sp ? (nat_fp[1] << 16 | nat_fp[0] << 24) : 0),
1);
} }
/* Validate filter spec against configuration done on the card. */ /* Validate filter spec against configuration done on the card. */
...@@ -909,6 +913,9 @@ int set_filter_wr(struct adapter *adapter, int fidx) ...@@ -909,6 +913,9 @@ int set_filter_wr(struct adapter *adapter, int fidx)
fwr->fpm = htons(f->fs.mask.fport); fwr->fpm = htons(f->fs.mask.fport);
if (adapter->params.filter2_wr_support) { if (adapter->params.filter2_wr_support) {
u8 *nat_lp = (u8 *)&f->fs.nat_lport;
u8 *nat_fp = (u8 *)&f->fs.nat_fport;
fwr->natmode_to_ulp_type = fwr->natmode_to_ulp_type =
FW_FILTER2_WR_ULP_TYPE_V(f->fs.nat_mode ? FW_FILTER2_WR_ULP_TYPE_V(f->fs.nat_mode ?
ULP_MODE_TCPDDP : ULP_MODE_TCPDDP :
...@@ -916,8 +923,8 @@ int set_filter_wr(struct adapter *adapter, int fidx) ...@@ -916,8 +923,8 @@ int set_filter_wr(struct adapter *adapter, int fidx)
FW_FILTER2_WR_NATMODE_V(f->fs.nat_mode); FW_FILTER2_WR_NATMODE_V(f->fs.nat_mode);
memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip)); memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip)); memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
fwr->newlport = htons(f->fs.nat_lport); fwr->newlport = htons(nat_lp[1] | nat_lp[0] << 8);
fwr->newfport = htons(f->fs.nat_fport); fwr->newfport = htons(nat_fp[1] | nat_fp[0] << 8);
} }
/* Mark the filter as "pending" and ship off the Filter Work Request. /* Mark the filter as "pending" and ship off the Filter Work Request.
......
...@@ -2609,7 +2609,7 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, ...@@ -2609,7 +2609,7 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
/* Clear out filter specifications */ /* Clear out filter specifications */
memset(&f->fs, 0, sizeof(struct ch_filter_specification)); memset(&f->fs, 0, sizeof(struct ch_filter_specification));
f->fs.val.lport = cpu_to_be16(sport); f->fs.val.lport = be16_to_cpu(sport);
f->fs.mask.lport = ~0; f->fs.mask.lport = ~0;
val = (u8 *)&sip; val = (u8 *)&sip;
if ((val[0] | val[1] | val[2] | val[3]) != 0) { if ((val[0] | val[1] | val[2] | val[3]) != 0) {
......
...@@ -58,10 +58,6 @@ static struct ch_tc_pedit_fields pedits[] = { ...@@ -58,10 +58,6 @@ static struct ch_tc_pedit_fields pedits[] = {
PEDIT_FIELDS(IP6_, DST_63_32, 4, nat_lip, 4), PEDIT_FIELDS(IP6_, DST_63_32, 4, nat_lip, 4),
PEDIT_FIELDS(IP6_, DST_95_64, 4, nat_lip, 8), PEDIT_FIELDS(IP6_, DST_95_64, 4, nat_lip, 8),
PEDIT_FIELDS(IP6_, DST_127_96, 4, nat_lip, 12), PEDIT_FIELDS(IP6_, DST_127_96, 4, nat_lip, 12),
PEDIT_FIELDS(TCP_, SPORT, 2, nat_fport, 0),
PEDIT_FIELDS(TCP_, DPORT, 2, nat_lport, 0),
PEDIT_FIELDS(UDP_, SPORT, 2, nat_fport, 0),
PEDIT_FIELDS(UDP_, DPORT, 2, nat_lport, 0),
}; };
static struct ch_tc_flower_entry *allocate_flower_entry(void) static struct ch_tc_flower_entry *allocate_flower_entry(void)
...@@ -156,14 +152,14 @@ static void cxgb4_process_flow_match(struct net_device *dev, ...@@ -156,14 +152,14 @@ static void cxgb4_process_flow_match(struct net_device *dev,
struct flow_match_ports match; struct flow_match_ports match;
flow_rule_match_ports(rule, &match); flow_rule_match_ports(rule, &match);
fs->val.lport = cpu_to_be16(match.key->dst); fs->val.lport = be16_to_cpu(match.key->dst);
fs->mask.lport = cpu_to_be16(match.mask->dst); fs->mask.lport = be16_to_cpu(match.mask->dst);
fs->val.fport = cpu_to_be16(match.key->src); fs->val.fport = be16_to_cpu(match.key->src);
fs->mask.fport = cpu_to_be16(match.mask->src); fs->mask.fport = be16_to_cpu(match.mask->src);
/* also initialize nat_lport/fport to same values */ /* also initialize nat_lport/fport to same values */
fs->nat_lport = cpu_to_be16(match.key->dst); fs->nat_lport = fs->val.lport;
fs->nat_fport = cpu_to_be16(match.key->src); fs->nat_fport = fs->val.fport;
} }
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
...@@ -354,12 +350,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -354,12 +350,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
switch (offset) { switch (offset) {
case PEDIT_TCP_SPORT_DPORT: case PEDIT_TCP_SPORT_DPORT:
if (~mask & PEDIT_TCP_UDP_SPORT_MASK) if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
offload_pedit(fs, cpu_to_be32(val) >> 16, fs->nat_fport = val;
cpu_to_be32(mask) >> 16,
TCP_SPORT);
else else
offload_pedit(fs, cpu_to_be32(val), fs->nat_lport = val >> 16;
cpu_to_be32(mask), TCP_DPORT);
} }
fs->nat_mode = NAT_MODE_ALL; fs->nat_mode = NAT_MODE_ALL;
break; break;
...@@ -367,12 +360,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -367,12 +360,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
switch (offset) { switch (offset) {
case PEDIT_UDP_SPORT_DPORT: case PEDIT_UDP_SPORT_DPORT:
if (~mask & PEDIT_TCP_UDP_SPORT_MASK) if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
offload_pedit(fs, cpu_to_be32(val) >> 16, fs->nat_fport = val;
cpu_to_be32(mask) >> 16,
UDP_SPORT);
else else
offload_pedit(fs, cpu_to_be32(val), fs->nat_lport = val >> 16;
cpu_to_be32(mask), UDP_DPORT);
} }
fs->nat_mode = NAT_MODE_ALL; fs->nat_mode = NAT_MODE_ALL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment