Lines Matching full:flow

39 /* Return the dst fid of the func for flow forwarding
174 struct bnxt_tc_flow *flow) in bnxt_tc_parse_flow() argument
191 flow->l2_key.ether_type = match.key->n_proto; in bnxt_tc_parse_flow()
192 flow->l2_mask.ether_type = match.mask->n_proto; in bnxt_tc_parse_flow()
196 flow->l4_key.ip_proto = match.key->ip_proto; in bnxt_tc_parse_flow()
197 flow->l4_mask.ip_proto = match.mask->ip_proto; in bnxt_tc_parse_flow()
205 flow->flags |= BNXT_TC_FLOW_FLAGS_ETH_ADDRS; in bnxt_tc_parse_flow()
206 ether_addr_copy(flow->l2_key.dmac, match.key->dst); in bnxt_tc_parse_flow()
207 ether_addr_copy(flow->l2_mask.dmac, match.mask->dst); in bnxt_tc_parse_flow()
208 ether_addr_copy(flow->l2_key.smac, match.key->src); in bnxt_tc_parse_flow()
209 ether_addr_copy(flow->l2_mask.smac, match.mask->src); in bnxt_tc_parse_flow()
216 flow->l2_key.inner_vlan_tci = in bnxt_tc_parse_flow()
219 flow->l2_mask.inner_vlan_tci = in bnxt_tc_parse_flow()
222 flow->l2_key.inner_vlan_tpid = htons(ETH_P_8021Q); in bnxt_tc_parse_flow()
223 flow->l2_mask.inner_vlan_tpid = htons(0xffff); in bnxt_tc_parse_flow()
224 flow->l2_key.num_vlans = 1; in bnxt_tc_parse_flow()
231 flow->flags |= BNXT_TC_FLOW_FLAGS_IPV4_ADDRS; in bnxt_tc_parse_flow()
232 flow->l3_key.ipv4.daddr.s_addr = match.key->dst; in bnxt_tc_parse_flow()
233 flow->l3_mask.ipv4.daddr.s_addr = match.mask->dst; in bnxt_tc_parse_flow()
234 flow->l3_key.ipv4.saddr.s_addr = match.key->src; in bnxt_tc_parse_flow()
235 flow->l3_mask.ipv4.saddr.s_addr = match.mask->src; in bnxt_tc_parse_flow()
240 flow->flags |= BNXT_TC_FLOW_FLAGS_IPV6_ADDRS; in bnxt_tc_parse_flow()
241 flow->l3_key.ipv6.daddr = match.key->dst; in bnxt_tc_parse_flow()
242 flow->l3_mask.ipv6.daddr = match.mask->dst; in bnxt_tc_parse_flow()
243 flow->l3_key.ipv6.saddr = match.key->src; in bnxt_tc_parse_flow()
244 flow->l3_mask.ipv6.saddr = match.mask->src; in bnxt_tc_parse_flow()
251 flow->flags |= BNXT_TC_FLOW_FLAGS_PORTS; in bnxt_tc_parse_flow()
252 flow->l4_key.ports.dport = match.key->dst; in bnxt_tc_parse_flow()
253 flow->l4_mask.ports.dport = match.mask->dst; in bnxt_tc_parse_flow()
254 flow->l4_key.ports.sport = match.key->src; in bnxt_tc_parse_flow()
255 flow->l4_mask.ports.sport = match.mask->src; in bnxt_tc_parse_flow()
262 flow->flags |= BNXT_TC_FLOW_FLAGS_ICMP; in bnxt_tc_parse_flow()
263 flow->l4_key.icmp.type = match.key->type; in bnxt_tc_parse_flow()
264 flow->l4_key.icmp.code = match.key->code; in bnxt_tc_parse_flow()
265 flow->l4_mask.icmp.type = match.mask->type; in bnxt_tc_parse_flow()
266 flow->l4_mask.icmp.code = match.mask->code; in bnxt_tc_parse_flow()
273 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS; in bnxt_tc_parse_flow()
274 flow->tun_key.u.ipv4.dst = match.key->dst; in bnxt_tc_parse_flow()
275 flow->tun_mask.u.ipv4.dst = match.mask->dst; in bnxt_tc_parse_flow()
276 flow->tun_key.u.ipv4.src = match.key->src; in bnxt_tc_parse_flow()
277 flow->tun_mask.u.ipv4.src = match.mask->src; in bnxt_tc_parse_flow()
287 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_ID; in bnxt_tc_parse_flow()
288 flow->tun_key.tun_id = key32_to_tunnel_id(match.key->keyid); in bnxt_tc_parse_flow()
289 flow->tun_mask.tun_id = key32_to_tunnel_id(match.mask->keyid); in bnxt_tc_parse_flow()
296 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_PORTS; in bnxt_tc_parse_flow()
297 flow->tun_key.tp_dst = match.key->dst; in bnxt_tc_parse_flow()
298 flow->tun_mask.tp_dst = match.mask->dst; in bnxt_tc_parse_flow()
299 flow->tun_key.tp_src = match.key->src; in bnxt_tc_parse_flow()
300 flow->tun_mask.tp_src = match.mask->src; in bnxt_tc_parse_flow()
303 return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action); in bnxt_tc_parse_flow()
386 static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_hwrm_cfa_flow_alloc() argument
391 struct bnxt_tc_actions *actions = &flow->actions; in bnxt_hwrm_cfa_flow_alloc()
392 struct bnxt_tc_l3_key *l3_mask = &flow->l3_mask; in bnxt_hwrm_cfa_flow_alloc()
393 struct bnxt_tc_l3_key *l3_key = &flow->l3_key; in bnxt_hwrm_cfa_flow_alloc()
401 req.src_fid = cpu_to_le16(flow->src_fid); in bnxt_hwrm_cfa_flow_alloc()
411 req.ethertype = flow->l2_key.ether_type; in bnxt_hwrm_cfa_flow_alloc()
412 req.ip_proto = flow->l4_key.ip_proto; in bnxt_hwrm_cfa_flow_alloc()
414 if (flow->flags & BNXT_TC_FLOW_FLAGS_ETH_ADDRS) { in bnxt_hwrm_cfa_flow_alloc()
415 memcpy(req.dmac, flow->l2_key.dmac, ETH_ALEN); in bnxt_hwrm_cfa_flow_alloc()
416 memcpy(req.smac, flow->l2_key.smac, ETH_ALEN); in bnxt_hwrm_cfa_flow_alloc()
419 if (flow->l2_key.num_vlans > 0) { in bnxt_hwrm_cfa_flow_alloc()
425 req.outer_vlan_tci = flow->l2_key.inner_vlan_tci; in bnxt_hwrm_cfa_flow_alloc()
428 /* If all IP and L4 fields are wildcarded then this is an L2 flow */ in bnxt_hwrm_cfa_flow_alloc()
430 is_wildcard(&flow->l4_mask, sizeof(flow->l4_mask))) { in bnxt_hwrm_cfa_flow_alloc()
433 flow_flags |= flow->l2_key.ether_type == htons(ETH_P_IP) ? in bnxt_hwrm_cfa_flow_alloc()
437 if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV4_ADDRS) { in bnxt_hwrm_cfa_flow_alloc()
444 } else if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV6_ADDRS) { in bnxt_hwrm_cfa_flow_alloc()
456 if (flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) { in bnxt_hwrm_cfa_flow_alloc()
457 req.l4_src_port = flow->l4_key.ports.sport; in bnxt_hwrm_cfa_flow_alloc()
458 req.l4_src_port_mask = flow->l4_mask.ports.sport; in bnxt_hwrm_cfa_flow_alloc()
459 req.l4_dst_port = flow->l4_key.ports.dport; in bnxt_hwrm_cfa_flow_alloc()
460 req.l4_dst_port_mask = flow->l4_mask.ports.dport; in bnxt_hwrm_cfa_flow_alloc()
461 } else if (flow->flags & BNXT_TC_FLOW_FLAGS_ICMP) { in bnxt_hwrm_cfa_flow_alloc()
463 req.l4_src_port = htons(flow->l4_key.icmp.type); in bnxt_hwrm_cfa_flow_alloc()
464 req.l4_src_port_mask = htons(flow->l4_mask.icmp.type); in bnxt_hwrm_cfa_flow_alloc()
465 req.l4_dst_port = htons(flow->l4_key.icmp.code); in bnxt_hwrm_cfa_flow_alloc()
466 req.l4_dst_port_mask = htons(flow->l4_mask.icmp.code); in bnxt_hwrm_cfa_flow_alloc()
503 * flow handle flow handle in bnxt_hwrm_cfa_flow_alloc()
505 * flow_handle flow handle flow context id in bnxt_hwrm_cfa_flow_alloc()
506 * ext_flow_handle INVALID flow handle in bnxt_hwrm_cfa_flow_alloc()
507 * flow_id INVALID flow counter id in bnxt_hwrm_cfa_flow_alloc()
520 struct bnxt_tc_flow *flow, in hwrm_cfa_decap_filter_alloc() argument
527 struct ip_tunnel_key *tun_key = &flow->tun_key; in hwrm_cfa_decap_filter_alloc()
539 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ID) { in hwrm_cfa_decap_filter_alloc()
545 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS) { in hwrm_cfa_decap_filter_alloc()
557 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS) { in hwrm_cfa_decap_filter_alloc()
566 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_PORTS) { in hwrm_cfa_decap_filter_alloc()
678 /* remove flow_node from the L2 shared flow list */ in bnxt_tc_put_l2_node()
723 /* Get the ref_flow_handle for a flow by checking if there are any other
724 * flows that share the same L2 key as this flow.
727 bnxt_tc_get_ref_flow_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_get_ref_flow_handle() argument
737 &flow->l2_key); in bnxt_tc_get_ref_flow_handle()
741 /* If any other flow is using this l2_node, use it's flow_handle in bnxt_tc_get_ref_flow_handle()
754 * with a matching l2 key can use the flow_handle of this flow in bnxt_tc_get_ref_flow_handle()
763 /* After the flow parsing is done, this routine is used for checking
764 * if there are any aspects of the flow that prevent it from being
767 static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow) in bnxt_tc_can_offload() argument
770 if ((flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) && in bnxt_tc_can_offload()
771 (flow->l4_key.ip_proto != IPPROTO_TCP && in bnxt_tc_can_offload()
772 flow->l4_key.ip_proto != IPPROTO_UDP)) { in bnxt_tc_can_offload()
774 flow->l4_key.ip_proto); in bnxt_tc_can_offload()
779 if (bits_set(&flow->l2_key.smac, sizeof(flow->l2_key.smac)) && in bnxt_tc_can_offload()
780 !is_exactmatch(flow->l2_mask.smac, sizeof(flow->l2_mask.smac))) { in bnxt_tc_can_offload()
784 if (bits_set(&flow->l2_key.dmac, sizeof(flow->l2_key.dmac)) && in bnxt_tc_can_offload()
785 !is_exactmatch(&flow->l2_mask.dmac, sizeof(flow->l2_mask.dmac))) { in bnxt_tc_can_offload()
791 if (bits_set(&flow->l2_key.inner_vlan_tci, in bnxt_tc_can_offload()
792 sizeof(flow->l2_key.inner_vlan_tci)) && in bnxt_tc_can_offload()
793 !is_vlan_tci_allowed(flow->l2_mask.inner_vlan_tci, in bnxt_tc_can_offload()
794 flow->l2_key.inner_vlan_tci)) { in bnxt_tc_can_offload()
798 if (bits_set(&flow->l2_key.inner_vlan_tpid, in bnxt_tc_can_offload()
799 sizeof(flow->l2_key.inner_vlan_tpid)) && in bnxt_tc_can_offload()
800 !is_exactmatch(&flow->l2_mask.inner_vlan_tpid, in bnxt_tc_can_offload()
801 sizeof(flow->l2_mask.inner_vlan_tpid))) { in bnxt_tc_can_offload()
807 if (!is_exactmatch(&flow->l2_mask.ether_type, in bnxt_tc_can_offload()
808 sizeof(flow->l2_mask.ether_type))) { in bnxt_tc_can_offload()
876 struct bnxt_tc_flow *flow, in bnxt_tc_get_ref_decap_handle() argument
891 /* If any other flow is using this decap_l2_node, use it's decap_handle in bnxt_tc_get_ref_decap_handle()
906 * this flow as their ref_decap_handle in bnxt_tc_get_ref_decap_handle()
922 /* remove flow_node from the decap L2 sharing flow list */ in bnxt_tc_put_decap_l2_node()
957 struct flowi4 flow = { {0} }; in bnxt_tc_resolve_tunnel_hdrs() local
963 flow.flowi4_proto = IPPROTO_UDP; in bnxt_tc_resolve_tunnel_hdrs()
964 flow.fl4_dport = tun_key->tp_dst; in bnxt_tc_resolve_tunnel_hdrs()
965 flow.daddr = tun_key->u.ipv4.dst; in bnxt_tc_resolve_tunnel_hdrs()
967 rt = ip_route_output_key(dev_net(real_dst_dev), &flow); in bnxt_tc_resolve_tunnel_hdrs()
969 netdev_info(bp->dev, "no route to %pI4b", &flow.daddr); in bnxt_tc_resolve_tunnel_hdrs()
996 netdev_name(dst_dev), &flow.daddr, in bnxt_tc_resolve_tunnel_hdrs()
1002 nbr = dst_neigh_lookup(&rt->dst, &flow.daddr); in bnxt_tc_resolve_tunnel_hdrs()
1005 &flow.daddr); in bnxt_tc_resolve_tunnel_hdrs()
1010 tun_key->u.ipv4.src = flow.saddr; in bnxt_tc_resolve_tunnel_hdrs()
1026 static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_get_decap_handle() argument
1030 struct ip_tunnel_key *decap_key = &flow->tun_key; in bnxt_tc_get_decap_handle()
1039 /* Check if there's another flow using the same tunnel decap. in bnxt_tc_get_decap_handle()
1060 tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src; in bnxt_tc_get_decap_handle()
1061 tun_key.tp_dst = flow->tun_key.tp_dst; in bnxt_tc_get_decap_handle()
1074 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS; in bnxt_tc_get_decap_handle()
1078 * key and if so, pass that flow's decap_filter_handle as the in bnxt_tc_get_decap_handle()
1079 * ref_decap_handle for this flow. in bnxt_tc_get_decap_handle()
1081 rc = bnxt_tc_get_ref_decap_handle(bp, flow, decap_l2_info, flow_node, in bnxt_tc_get_decap_handle()
1087 rc = hwrm_cfa_decap_filter_alloc(bp, flow, decap_l2_info, in bnxt_tc_get_decap_handle()
1124 static int bnxt_tc_get_encap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_get_encap_handle() argument
1128 struct ip_tunnel_key *encap_key = &flow->actions.tun_encap_key; in bnxt_tc_get_encap_handle()
1133 /* Check if there's another flow using the same tunnel encap. in bnxt_tc_get_encap_handle()
1169 struct bnxt_tc_flow *flow, in bnxt_tc_put_tunnel_handle() argument
1172 if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) in bnxt_tc_put_tunnel_handle()
1174 else if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) in bnxt_tc_put_tunnel_handle()
1179 struct bnxt_tc_flow *flow, in bnxt_tc_get_tunnel_handle() argument
1183 if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) in bnxt_tc_get_tunnel_handle()
1184 return bnxt_tc_get_decap_handle(bp, flow, flow_node, in bnxt_tc_get_tunnel_handle()
1186 else if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) in bnxt_tc_get_tunnel_handle()
1187 return bnxt_tc_get_encap_handle(bp, flow, flow_node, in bnxt_tc_get_tunnel_handle()
1198 /* send HWRM cmd to free the flow-id */ in __bnxt_tc_del_flow()
1204 bnxt_tc_put_tunnel_handle(bp, &flow_node->flow, flow_node); in __bnxt_tc_del_flow()
1221 static void bnxt_tc_set_flow_dir(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_set_flow_dir() argument
1224 flow->l2_key.dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX; in bnxt_tc_set_flow_dir()
1227 static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_set_src_fid() argument
1230 if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) in bnxt_tc_set_src_fid()
1231 flow->src_fid = bp->pf.fw_fid; in bnxt_tc_set_src_fid()
1233 flow->src_fid = src_fid; in bnxt_tc_set_src_fid()
1236 /* Add a new flow or replace an existing flow.
1239 * 1. while adding a new flow
1242 * c) link l2-key with flow
1243 * 2. while deleting a flow
1244 * a) unlinking l2-key from flow
1254 struct bnxt_tc_flow *flow; in bnxt_tc_add_flow() local
1259 /* allocate memory for the new flow and it's node */ in bnxt_tc_add_flow()
1266 flow = &new_node->flow; in bnxt_tc_add_flow()
1268 rc = bnxt_tc_parse_flow(bp, tc_flow_cmd, flow); in bnxt_tc_add_flow()
1272 bnxt_tc_set_src_fid(bp, flow, src_fid); in bnxt_tc_add_flow()
1273 bnxt_tc_set_flow_dir(bp, flow, flow->src_fid); in bnxt_tc_add_flow()
1275 if (!bnxt_tc_can_offload(bp, flow)) { in bnxt_tc_add_flow()
1280 /* If a flow exists with the same cookie, delete it */ in bnxt_tc_add_flow()
1287 /* Check if the L2 part of the flow has been offloaded already. in bnxt_tc_add_flow()
1291 rc = bnxt_tc_get_ref_flow_handle(bp, flow, new_node, &ref_flow_handle); in bnxt_tc_add_flow()
1295 /* If the flow involves tunnel encap/decap, get tunnel_handle */ in bnxt_tc_add_flow()
1296 rc = bnxt_tc_get_tunnel_handle(bp, flow, new_node, &tunnel_handle); in bnxt_tc_add_flow()
1300 /* send HWRM cmd to alloc the flow */ in bnxt_tc_add_flow()
1301 rc = bnxt_hwrm_cfa_flow_alloc(bp, flow, ref_flow_handle, in bnxt_tc_add_flow()
1306 flow->lastused = jiffies; in bnxt_tc_add_flow()
1307 spin_lock_init(&flow->stats_lock); in bnxt_tc_add_flow()
1308 /* add new flow to flow-table */ in bnxt_tc_add_flow()
1320 bnxt_tc_put_tunnel_handle(bp, flow, new_node); in bnxt_tc_add_flow()
1354 struct bnxt_tc_flow *flow; in bnxt_tc_get_flow_stats() local
1363 flow = &flow_node->flow; in bnxt_tc_get_flow_stats()
1364 curr_stats = &flow->stats; in bnxt_tc_get_flow_stats()
1365 prev_stats = &flow->prev_stats; in bnxt_tc_get_flow_stats()
1367 spin_lock(&flow->stats_lock); in bnxt_tc_get_flow_stats()
1371 lastused = flow->lastused; in bnxt_tc_get_flow_stats()
1372 spin_unlock(&flow->stats_lock); in bnxt_tc_get_flow_stats()
1388 /* If flow_id is used to fetch flow stats then: in bnxt_fill_cfa_stats_req()
1390 * 2. 15th bit of flow_handle must specify the flow in bnxt_fill_cfa_stats_req()
1393 if (flow_node->flow.l2_key.dir == BNXT_DIR_RX) in bnxt_fill_cfa_stats_req()
1488 struct bnxt_tc_flow *flow = &flow_node->flow; in bnxt_tc_flow_stats_batch_update() local
1490 spin_lock(&flow->stats_lock); in bnxt_tc_flow_stats_batch_update()
1491 bnxt_flow_stats_accum(tc_info, &flow->stats, in bnxt_tc_flow_stats_batch_update()
1493 if (flow->stats.packets != flow->prev_stats.packets) in bnxt_tc_flow_stats_batch_update()
1494 flow->lastused = jiffies; in bnxt_tc_flow_stats_batch_update()
1495 spin_unlock(&flow->stats_lock); in bnxt_tc_flow_stats_batch_update()