aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-08-28 18:20:25 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-28 18:20:25 -0400
commitc73c8a8e0726710f397f8ddce21ef9897e6693e2 (patch)
tree96f56a13c4ccbe37a3e073b5d5896ce9e7ea5ae5
parent77146b5d79cfa51aebb8c0e8c19af32b579890f7 (diff)
parent6afd33e4384060e692705912337b184c1e159aff (diff)
Merge branch 'nfp-flow-dissector-layer'
Pieter Jansen van Vuuren says: ==================== nfp: fix layer calculation and flow dissector use Previously when calculating the supported key layers MPLS, IPv4/6 TTL and TOS were not considered. Formerly flow dissectors were referenced without first checking that they are in use and correctly populated by TC. Additionally this patch set fixes the incorrect use of mask field for vlan matching. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/match.c139
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c60
2 files changed, 113 insertions, 86 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index 0e08404480ef..d25b5038c3a2 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -42,33 +42,29 @@ nfp_flower_compile_meta_tci(struct nfp_flower_meta_two *frame,
42 struct tc_cls_flower_offload *flow, u8 key_type, 42 struct tc_cls_flower_offload *flow, u8 key_type,
43 bool mask_version) 43 bool mask_version)
44{ 44{
45 struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
45 struct flow_dissector_key_vlan *flow_vlan; 46 struct flow_dissector_key_vlan *flow_vlan;
46 u16 tmp_tci; 47 u16 tmp_tci;
47 48
49 memset(frame, 0, sizeof(struct nfp_flower_meta_two));
48 /* Populate the metadata frame. */ 50 /* Populate the metadata frame. */
49 frame->nfp_flow_key_layer = key_type; 51 frame->nfp_flow_key_layer = key_type;
50 frame->mask_id = ~0; 52 frame->mask_id = ~0;
51 53
52 if (mask_version) { 54 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
53 frame->tci = cpu_to_be16(~0); 55 flow_vlan = skb_flow_dissector_target(flow->dissector,
54 return; 56 FLOW_DISSECTOR_KEY_VLAN,
55 } 57 target);
56 58 /* Populate the tci field. */
57 flow_vlan = skb_flow_dissector_target(flow->dissector, 59 if (flow_vlan->vlan_id) {
58 FLOW_DISSECTOR_KEY_VLAN, 60 tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
59 flow->key); 61 flow_vlan->vlan_priority) |
60 62 FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
61 /* Populate the tci field. */ 63 flow_vlan->vlan_id) |
62 if (!flow_vlan->vlan_id) { 64 NFP_FLOWER_MASK_VLAN_CFI;
63 tmp_tci = 0; 65 frame->tci = cpu_to_be16(tmp_tci);
64 } else { 66 }
65 tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
66 flow_vlan->vlan_priority) |
67 FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
68 flow_vlan->vlan_id) |
69 NFP_FLOWER_MASK_VLAN_CFI;
70 } 67 }
71 frame->tci = cpu_to_be16(tmp_tci);
72} 68}
73 69
74static void 70static void
@@ -99,17 +95,18 @@ nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
99 bool mask_version) 95 bool mask_version)
100{ 96{
101 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 97 struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
102 struct flow_dissector_key_eth_addrs *flow_mac; 98 struct flow_dissector_key_eth_addrs *addr;
103
104 flow_mac = skb_flow_dissector_target(flow->dissector,
105 FLOW_DISSECTOR_KEY_ETH_ADDRS,
106 target);
107 99
108 memset(frame, 0, sizeof(struct nfp_flower_mac_mpls)); 100 memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
109 101
110 /* Populate mac frame. */ 102 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
111 ether_addr_copy(frame->mac_dst, &flow_mac->dst[0]); 103 addr = skb_flow_dissector_target(flow->dissector,
112 ether_addr_copy(frame->mac_src, &flow_mac->src[0]); 104 FLOW_DISSECTOR_KEY_ETH_ADDRS,
105 target);
106 /* Populate mac frame. */
107 ether_addr_copy(frame->mac_dst, &addr->dst[0]);
108 ether_addr_copy(frame->mac_src, &addr->src[0]);
109 }
113 110
114 if (mask_version) 111 if (mask_version)
115 frame->mpls_lse = cpu_to_be32(~0); 112 frame->mpls_lse = cpu_to_be32(~0);
@@ -121,14 +118,17 @@ nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
121 bool mask_version) 118 bool mask_version)
122{ 119{
123 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 120 struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
124 struct flow_dissector_key_ports *flow_tp; 121 struct flow_dissector_key_ports *tp;
125 122
126 flow_tp = skb_flow_dissector_target(flow->dissector, 123 memset(frame, 0, sizeof(struct nfp_flower_tp_ports));
127 FLOW_DISSECTOR_KEY_PORTS,
128 target);
129 124
130 frame->port_src = flow_tp->src; 125 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
131 frame->port_dst = flow_tp->dst; 126 tp = skb_flow_dissector_target(flow->dissector,
127 FLOW_DISSECTOR_KEY_PORTS,
128 target);
129 frame->port_src = tp->src;
130 frame->port_dst = tp->dst;
131 }
132} 132}
133 133
134static void 134static void
@@ -137,25 +137,27 @@ nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
137 bool mask_version) 137 bool mask_version)
138{ 138{
139 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 139 struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
140 struct flow_dissector_key_ipv4_addrs *flow_ipv4; 140 struct flow_dissector_key_ipv4_addrs *addr;
141 struct flow_dissector_key_basic *flow_basic; 141 struct flow_dissector_key_basic *basic;
142
143 flow_ipv4 = skb_flow_dissector_target(flow->dissector,
144 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
145 target);
146
147 flow_basic = skb_flow_dissector_target(flow->dissector,
148 FLOW_DISSECTOR_KEY_BASIC,
149 target);
150 142
151 /* Populate IPv4 frame. */
152 frame->reserved = 0;
153 frame->ipv4_src = flow_ipv4->src;
154 frame->ipv4_dst = flow_ipv4->dst;
155 frame->proto = flow_basic->ip_proto;
156 /* Wildcard TOS/TTL for now. */ 143 /* Wildcard TOS/TTL for now. */
157 frame->tos = 0; 144 memset(frame, 0, sizeof(struct nfp_flower_ipv4));
158 frame->ttl = 0; 145
146 if (dissector_uses_key(flow->dissector,
147 FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
148 addr = skb_flow_dissector_target(flow->dissector,
149 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
150 target);
151 frame->ipv4_src = addr->src;
152 frame->ipv4_dst = addr->dst;
153 }
154
155 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
156 basic = skb_flow_dissector_target(flow->dissector,
157 FLOW_DISSECTOR_KEY_BASIC,
158 target);
159 frame->proto = basic->ip_proto;
160 }
159} 161}
160 162
161static void 163static void
@@ -164,26 +166,27 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
164 bool mask_version) 166 bool mask_version)
165{ 167{
166 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 168 struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
167 struct flow_dissector_key_ipv6_addrs *flow_ipv6; 169 struct flow_dissector_key_ipv6_addrs *addr;
168 struct flow_dissector_key_basic *flow_basic; 170 struct flow_dissector_key_basic *basic;
169
170 flow_ipv6 = skb_flow_dissector_target(flow->dissector,
171 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
172 target);
173 171
174 flow_basic = skb_flow_dissector_target(flow->dissector,
175 FLOW_DISSECTOR_KEY_BASIC,
176 target);
177
178 /* Populate IPv6 frame. */
179 frame->reserved = 0;
180 frame->ipv6_src = flow_ipv6->src;
181 frame->ipv6_dst = flow_ipv6->dst;
182 frame->proto = flow_basic->ip_proto;
183 /* Wildcard LABEL/TOS/TTL for now. */ 172 /* Wildcard LABEL/TOS/TTL for now. */
184 frame->ipv6_flow_label_exthdr = 0; 173 memset(frame, 0, sizeof(struct nfp_flower_ipv6));
185 frame->tos = 0; 174
186 frame->ttl = 0; 175 if (dissector_uses_key(flow->dissector,
176 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
177 addr = skb_flow_dissector_target(flow->dissector,
178 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
179 target);
180 frame->ipv6_src = addr->src;
181 frame->ipv6_dst = addr->dst;
182 }
183
184 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
185 basic = skb_flow_dissector_target(flow->dissector,
186 FLOW_DISSECTOR_KEY_BASIC,
187 target);
188 frame->proto = basic->ip_proto;
189 }
187} 190}
188 191
189int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, 192int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index 4ad10bd5e139..74a96d6bb05c 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -105,43 +105,62 @@ static int
105nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, 105nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
106 struct tc_cls_flower_offload *flow) 106 struct tc_cls_flower_offload *flow)
107{ 107{
108 struct flow_dissector_key_control *mask_enc_ctl; 108 struct flow_dissector_key_basic *mask_basic = NULL;
109 struct flow_dissector_key_basic *mask_basic; 109 struct flow_dissector_key_basic *key_basic = NULL;
110 struct flow_dissector_key_basic *key_basic; 110 struct flow_dissector_key_ip *mask_ip = NULL;
111 u32 key_layer_two; 111 u32 key_layer_two;
112 u8 key_layer; 112 u8 key_layer;
113 int key_size; 113 int key_size;
114 114
115 mask_enc_ctl = skb_flow_dissector_target(flow->dissector, 115 if (dissector_uses_key(flow->dissector,
116 FLOW_DISSECTOR_KEY_ENC_CONTROL, 116 FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
117 flow->mask); 117 struct flow_dissector_key_control *mask_enc_ctl =
118 skb_flow_dissector_target(flow->dissector,
119 FLOW_DISSECTOR_KEY_ENC_CONTROL,
120 flow->mask);
121 /* We are expecting a tunnel. For now we ignore offloading. */
122 if (mask_enc_ctl->addr_type)
123 return -EOPNOTSUPP;
124 }
118 125
119 mask_basic = skb_flow_dissector_target(flow->dissector, 126 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
120 FLOW_DISSECTOR_KEY_BASIC, 127 mask_basic = skb_flow_dissector_target(flow->dissector,
121 flow->mask); 128 FLOW_DISSECTOR_KEY_BASIC,
129 flow->mask);
130
131 key_basic = skb_flow_dissector_target(flow->dissector,
132 FLOW_DISSECTOR_KEY_BASIC,
133 flow->key);
134 }
135
136 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP))
137 mask_ip = skb_flow_dissector_target(flow->dissector,
138 FLOW_DISSECTOR_KEY_IP,
139 flow->mask);
122 140
123 key_basic = skb_flow_dissector_target(flow->dissector,
124 FLOW_DISSECTOR_KEY_BASIC,
125 flow->key);
126 key_layer_two = 0; 141 key_layer_two = 0;
127 key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC; 142 key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC;
128 key_size = sizeof(struct nfp_flower_meta_one) + 143 key_size = sizeof(struct nfp_flower_meta_one) +
129 sizeof(struct nfp_flower_in_port) + 144 sizeof(struct nfp_flower_in_port) +
130 sizeof(struct nfp_flower_mac_mpls); 145 sizeof(struct nfp_flower_mac_mpls);
131 146
132 /* We are expecting a tunnel. For now we ignore offloading. */ 147 if (mask_basic && mask_basic->n_proto) {
133 if (mask_enc_ctl->addr_type)
134 return -EOPNOTSUPP;
135
136 if (mask_basic->n_proto) {
137 /* Ethernet type is present in the key. */ 148 /* Ethernet type is present in the key. */
138 switch (key_basic->n_proto) { 149 switch (key_basic->n_proto) {
139 case cpu_to_be16(ETH_P_IP): 150 case cpu_to_be16(ETH_P_IP):
151 if (mask_ip && mask_ip->tos)
152 return -EOPNOTSUPP;
153 if (mask_ip && mask_ip->ttl)
154 return -EOPNOTSUPP;
140 key_layer |= NFP_FLOWER_LAYER_IPV4; 155 key_layer |= NFP_FLOWER_LAYER_IPV4;
141 key_size += sizeof(struct nfp_flower_ipv4); 156 key_size += sizeof(struct nfp_flower_ipv4);
142 break; 157 break;
143 158
144 case cpu_to_be16(ETH_P_IPV6): 159 case cpu_to_be16(ETH_P_IPV6):
160 if (mask_ip && mask_ip->tos)
161 return -EOPNOTSUPP;
162 if (mask_ip && mask_ip->ttl)
163 return -EOPNOTSUPP;
145 key_layer |= NFP_FLOWER_LAYER_IPV6; 164 key_layer |= NFP_FLOWER_LAYER_IPV6;
146 key_size += sizeof(struct nfp_flower_ipv6); 165 key_size += sizeof(struct nfp_flower_ipv6);
147 break; 166 break;
@@ -152,6 +171,11 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
152 case cpu_to_be16(ETH_P_ARP): 171 case cpu_to_be16(ETH_P_ARP):
153 return -EOPNOTSUPP; 172 return -EOPNOTSUPP;
154 173
174 /* Currently we do not offload MPLS. */
175 case cpu_to_be16(ETH_P_MPLS_UC):
176 case cpu_to_be16(ETH_P_MPLS_MC):
177 return -EOPNOTSUPP;
178
155 /* Will be included in layer 2. */ 179 /* Will be included in layer 2. */
156 case cpu_to_be16(ETH_P_8021Q): 180 case cpu_to_be16(ETH_P_8021Q):
157 break; 181 break;
@@ -166,7 +190,7 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
166 } 190 }
167 } 191 }
168 192
169 if (mask_basic->ip_proto) { 193 if (mask_basic && mask_basic->ip_proto) {
170 /* Ethernet type is present in the key. */ 194 /* Ethernet type is present in the key. */
171 switch (key_basic->ip_proto) { 195 switch (key_basic->ip_proto) {
172 case IPPROTO_TCP: 196 case IPPROTO_TCP: