1 /* 2 * Copyright (C) 2017 Netronome Systems, Inc. 3 * 4 * This software is dual licensed under the GNU General License Version 2, 5 * June 1991 as shown in the file COPYING in the top-level directory of this 6 * source tree or the BSD 2-Clause License provided below. You have the 7 * option to license this software under the complete terms of either license. 8 * 9 * The BSD 2-Clause License: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * 2. Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34 #include <linux/bitfield.h> 35 #include <net/pkt_cls.h> 36 37 #include "cmsg.h" 38 #include "main.h" 39 40 static void 41 nfp_flower_compile_meta_tci(struct nfp_flower_meta_two *frame, 42 struct tc_cls_flower_offload *flow, u8 key_type, 43 bool mask_version) 44 { 45 struct flow_dissector_key_vlan *flow_vlan; 46 u16 tmp_tci; 47 48 /* Populate the metadata frame. */ 49 frame->nfp_flow_key_layer = key_type; 50 frame->mask_id = ~0; 51 52 if (mask_version) { 53 frame->tci = cpu_to_be16(~0); 54 return; 55 } 56 57 flow_vlan = skb_flow_dissector_target(flow->dissector, 58 FLOW_DISSECTOR_KEY_VLAN, 59 flow->key); 60 61 /* Populate the tci field. */ 62 if (!flow_vlan->vlan_id) { 63 tmp_tci = 0; 64 } else { 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 } 71 frame->tci = cpu_to_be16(tmp_tci); 72 } 73 74 static void 75 nfp_flower_compile_meta(struct nfp_flower_meta_one *frame, u8 key_type) 76 { 77 frame->nfp_flow_key_layer = key_type; 78 frame->mask_id = 0; 79 frame->reserved = 0; 80 } 81 82 static int 83 nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port, 84 bool mask_version) 85 { 86 if (mask_version) { 87 frame->in_port = cpu_to_be32(~0); 88 return 0; 89 } 90 91 frame->in_port = cpu_to_be32(cmsg_port); 92 93 return 0; 94 } 95 96 static void 97 nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame, 98 struct tc_cls_flower_offload *flow, 99 bool mask_version) 100 { 101 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 102 struct flow_dissector_key_eth_addrs *flow_mac; 103 104 flow_mac = skb_flow_dissector_target(flow->dissector, 105 FLOW_DISSECTOR_KEY_ETH_ADDRS, 106 target); 107 108 memset(frame, 0, sizeof(struct nfp_flower_mac_mpls)); 109 110 /* Populate mac frame. */ 111 ether_addr_copy(frame->mac_dst, &flow_mac->dst[0]); 112 ether_addr_copy(frame->mac_src, &flow_mac->src[0]); 113 114 if (mask_version) 115 frame->mpls_lse = cpu_to_be32(~0); 116 } 117 118 static void 119 nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame, 120 struct tc_cls_flower_offload *flow, 121 bool mask_version) 122 { 123 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 124 struct flow_dissector_key_ports *flow_tp; 125 126 flow_tp = skb_flow_dissector_target(flow->dissector, 127 FLOW_DISSECTOR_KEY_PORTS, 128 target); 129 130 frame->port_src = flow_tp->src; 131 frame->port_dst = flow_tp->dst; 132 } 133 134 static void 135 nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame, 136 struct tc_cls_flower_offload *flow, 137 bool mask_version) 138 { 139 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 140 struct flow_dissector_key_ipv4_addrs *flow_ipv4; 141 struct flow_dissector_key_basic *flow_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 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. */ 157 frame->tos = 0; 158 frame->ttl = 0; 159 } 160 161 static void 162 nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame, 163 struct tc_cls_flower_offload *flow, 164 bool mask_version) 165 { 166 struct fl_flow_key *target = mask_version ? flow->mask : flow->key; 167 struct flow_dissector_key_ipv6_addrs *flow_ipv6; 168 struct flow_dissector_key_basic *flow_basic; 169 170 flow_ipv6 = skb_flow_dissector_target(flow->dissector, 171 FLOW_DISSECTOR_KEY_IPV6_ADDRS, 172 target); 173 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. */ 184 frame->ipv6_flow_label_exthdr = 0; 185 frame->tos = 0; 186 frame->ttl = 0; 187 } 188 189 int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, 190 struct nfp_fl_key_ls *key_ls, 191 struct net_device *netdev, 192 struct nfp_fl_payload *nfp_flow) 193 { 194 int err; 195 u8 *ext; 196 u8 *msk; 197 198 memset(nfp_flow->unmasked_data, 0, key_ls->key_size); 199 memset(nfp_flow->mask_data, 0, key_ls->key_size); 200 201 ext = nfp_flow->unmasked_data; 202 msk = nfp_flow->mask_data; 203 if (NFP_FLOWER_LAYER_PORT & key_ls->key_layer) { 204 /* Populate Exact Metadata. */ 205 nfp_flower_compile_meta_tci((struct nfp_flower_meta_two *)ext, 206 flow, key_ls->key_layer, false); 207 /* Populate Mask Metadata. */ 208 nfp_flower_compile_meta_tci((struct nfp_flower_meta_two *)msk, 209 flow, key_ls->key_layer, true); 210 ext += sizeof(struct nfp_flower_meta_two); 211 msk += sizeof(struct nfp_flower_meta_two); 212 213 /* Populate Exact Port data. */ 214 err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext, 215 nfp_repr_get_port_id(netdev), 216 false); 217 if (err) 218 return err; 219 220 /* Populate Mask Port Data. */ 221 err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk, 222 nfp_repr_get_port_id(netdev), 223 true); 224 if (err) 225 return err; 226 227 ext += sizeof(struct nfp_flower_in_port); 228 msk += sizeof(struct nfp_flower_in_port); 229 } else { 230 /* Populate Exact Metadata. */ 231 nfp_flower_compile_meta((struct nfp_flower_meta_one *)ext, 232 key_ls->key_layer); 233 /* Populate Mask Metadata. */ 234 nfp_flower_compile_meta((struct nfp_flower_meta_one *)msk, 235 key_ls->key_layer); 236 ext += sizeof(struct nfp_flower_meta_one); 237 msk += sizeof(struct nfp_flower_meta_one); 238 } 239 240 if (NFP_FLOWER_LAYER_META & key_ls->key_layer) { 241 /* Additional Metadata Fields. 242 * Currently unsupported. 243 */ 244 return -EOPNOTSUPP; 245 } 246 247 if (NFP_FLOWER_LAYER_MAC & key_ls->key_layer) { 248 /* Populate Exact MAC Data. */ 249 nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)ext, 250 flow, false); 251 /* Populate Mask MAC Data. */ 252 nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)msk, 253 flow, true); 254 ext += sizeof(struct nfp_flower_mac_mpls); 255 msk += sizeof(struct nfp_flower_mac_mpls); 256 } 257 258 if (NFP_FLOWER_LAYER_TP & key_ls->key_layer) { 259 /* Populate Exact TP Data. */ 260 nfp_flower_compile_tport((struct nfp_flower_tp_ports *)ext, 261 flow, false); 262 /* Populate Mask TP Data. */ 263 nfp_flower_compile_tport((struct nfp_flower_tp_ports *)msk, 264 flow, true); 265 ext += sizeof(struct nfp_flower_tp_ports); 266 msk += sizeof(struct nfp_flower_tp_ports); 267 } 268 269 if (NFP_FLOWER_LAYER_IPV4 & key_ls->key_layer) { 270 /* Populate Exact IPv4 Data. */ 271 nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)ext, 272 flow, false); 273 /* Populate Mask IPv4 Data. */ 274 nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)msk, 275 flow, true); 276 ext += sizeof(struct nfp_flower_ipv4); 277 msk += sizeof(struct nfp_flower_ipv4); 278 } 279 280 if (NFP_FLOWER_LAYER_IPV6 & key_ls->key_layer) { 281 /* Populate Exact IPv4 Data. */ 282 nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)ext, 283 flow, false); 284 /* Populate Mask IPv4 Data. */ 285 nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)msk, 286 flow, true); 287 ext += sizeof(struct nfp_flower_ipv6); 288 msk += sizeof(struct nfp_flower_ipv6); 289 } 290 291 return 0; 292 } 293