Lines Matching full:flow

43 /* Return the dst fid of the func for flow forwarding
369 struct bnxt_tc_flow *flow) in bnxt_tc_parse_flow() argument
386 flow->l2_key.ether_type = match.key->n_proto; in bnxt_tc_parse_flow()
387 flow->l2_mask.ether_type = match.mask->n_proto; in bnxt_tc_parse_flow()
391 flow->l4_key.ip_proto = match.key->ip_proto; in bnxt_tc_parse_flow()
392 flow->l4_mask.ip_proto = match.mask->ip_proto; in bnxt_tc_parse_flow()
400 flow->flags |= BNXT_TC_FLOW_FLAGS_ETH_ADDRS; in bnxt_tc_parse_flow()
401 ether_addr_copy(flow->l2_key.dmac, match.key->dst); in bnxt_tc_parse_flow()
402 ether_addr_copy(flow->l2_mask.dmac, match.mask->dst); in bnxt_tc_parse_flow()
403 ether_addr_copy(flow->l2_key.smac, match.key->src); in bnxt_tc_parse_flow()
404 ether_addr_copy(flow->l2_mask.smac, match.mask->src); in bnxt_tc_parse_flow()
411 flow->l2_key.inner_vlan_tci = in bnxt_tc_parse_flow()
414 flow->l2_mask.inner_vlan_tci = in bnxt_tc_parse_flow()
417 flow->l2_key.inner_vlan_tpid = htons(ETH_P_8021Q); in bnxt_tc_parse_flow()
418 flow->l2_mask.inner_vlan_tpid = htons(0xffff); in bnxt_tc_parse_flow()
419 flow->l2_key.num_vlans = 1; in bnxt_tc_parse_flow()
426 flow->flags |= BNXT_TC_FLOW_FLAGS_IPV4_ADDRS; in bnxt_tc_parse_flow()
427 flow->l3_key.ipv4.daddr.s_addr = match.key->dst; in bnxt_tc_parse_flow()
428 flow->l3_mask.ipv4.daddr.s_addr = match.mask->dst; in bnxt_tc_parse_flow()
429 flow->l3_key.ipv4.saddr.s_addr = match.key->src; in bnxt_tc_parse_flow()
430 flow->l3_mask.ipv4.saddr.s_addr = match.mask->src; in bnxt_tc_parse_flow()
435 flow->flags |= BNXT_TC_FLOW_FLAGS_IPV6_ADDRS; in bnxt_tc_parse_flow()
436 flow->l3_key.ipv6.daddr = match.key->dst; in bnxt_tc_parse_flow()
437 flow->l3_mask.ipv6.daddr = match.mask->dst; in bnxt_tc_parse_flow()
438 flow->l3_key.ipv6.saddr = match.key->src; in bnxt_tc_parse_flow()
439 flow->l3_mask.ipv6.saddr = match.mask->src; in bnxt_tc_parse_flow()
446 flow->flags |= BNXT_TC_FLOW_FLAGS_PORTS; in bnxt_tc_parse_flow()
447 flow->l4_key.ports.dport = match.key->dst; in bnxt_tc_parse_flow()
448 flow->l4_mask.ports.dport = match.mask->dst; in bnxt_tc_parse_flow()
449 flow->l4_key.ports.sport = match.key->src; in bnxt_tc_parse_flow()
450 flow->l4_mask.ports.sport = match.mask->src; in bnxt_tc_parse_flow()
457 flow->flags |= BNXT_TC_FLOW_FLAGS_ICMP; in bnxt_tc_parse_flow()
458 flow->l4_key.icmp.type = match.key->type; in bnxt_tc_parse_flow()
459 flow->l4_key.icmp.code = match.key->code; in bnxt_tc_parse_flow()
460 flow->l4_mask.icmp.type = match.mask->type; in bnxt_tc_parse_flow()
461 flow->l4_mask.icmp.code = match.mask->code; in bnxt_tc_parse_flow()
468 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS; in bnxt_tc_parse_flow()
469 flow->tun_key.u.ipv4.dst = match.key->dst; in bnxt_tc_parse_flow()
470 flow->tun_mask.u.ipv4.dst = match.mask->dst; in bnxt_tc_parse_flow()
471 flow->tun_key.u.ipv4.src = match.key->src; in bnxt_tc_parse_flow()
472 flow->tun_mask.u.ipv4.src = match.mask->src; in bnxt_tc_parse_flow()
482 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_ID; in bnxt_tc_parse_flow()
483 flow->tun_key.tun_id = key32_to_tunnel_id(match.key->keyid); in bnxt_tc_parse_flow()
484 flow->tun_mask.tun_id = key32_to_tunnel_id(match.mask->keyid); in bnxt_tc_parse_flow()
491 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_PORTS; in bnxt_tc_parse_flow()
492 flow->tun_key.tp_dst = match.key->dst; in bnxt_tc_parse_flow()
493 flow->tun_mask.tp_dst = match.mask->dst; in bnxt_tc_parse_flow()
494 flow->tun_key.tp_src = match.key->src; in bnxt_tc_parse_flow()
495 flow->tun_mask.tp_src = match.mask->src; in bnxt_tc_parse_flow()
498 return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action, in bnxt_tc_parse_flow()
582 static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_hwrm_cfa_flow_alloc() argument
587 struct bnxt_tc_actions *actions = &flow->actions; in bnxt_hwrm_cfa_flow_alloc()
588 struct bnxt_tc_l3_key *l3_mask = &flow->l3_mask; in bnxt_hwrm_cfa_flow_alloc()
589 struct bnxt_tc_l3_key *l3_key = &flow->l3_key; in bnxt_hwrm_cfa_flow_alloc()
597 req.src_fid = cpu_to_le16(flow->src_fid); in bnxt_hwrm_cfa_flow_alloc()
677 req.ethertype = flow->l2_key.ether_type; in bnxt_hwrm_cfa_flow_alloc()
678 req.ip_proto = flow->l4_key.ip_proto; in bnxt_hwrm_cfa_flow_alloc()
680 if (flow->flags & BNXT_TC_FLOW_FLAGS_ETH_ADDRS) { in bnxt_hwrm_cfa_flow_alloc()
681 memcpy(req.dmac, flow->l2_key.dmac, ETH_ALEN); in bnxt_hwrm_cfa_flow_alloc()
682 memcpy(req.smac, flow->l2_key.smac, ETH_ALEN); in bnxt_hwrm_cfa_flow_alloc()
685 if (flow->l2_key.num_vlans > 0) { in bnxt_hwrm_cfa_flow_alloc()
691 req.outer_vlan_tci = flow->l2_key.inner_vlan_tci; in bnxt_hwrm_cfa_flow_alloc()
694 /* If all IP and L4 fields are wildcarded then this is an L2 flow */ in bnxt_hwrm_cfa_flow_alloc()
696 is_wildcard(&flow->l4_mask, sizeof(flow->l4_mask))) { in bnxt_hwrm_cfa_flow_alloc()
699 flow_flags |= flow->l2_key.ether_type == htons(ETH_P_IP) ? in bnxt_hwrm_cfa_flow_alloc()
703 if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV4_ADDRS) { in bnxt_hwrm_cfa_flow_alloc()
710 } else if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV6_ADDRS) { in bnxt_hwrm_cfa_flow_alloc()
722 if (flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) { in bnxt_hwrm_cfa_flow_alloc()
723 req.l4_src_port = flow->l4_key.ports.sport; in bnxt_hwrm_cfa_flow_alloc()
724 req.l4_src_port_mask = flow->l4_mask.ports.sport; in bnxt_hwrm_cfa_flow_alloc()
725 req.l4_dst_port = flow->l4_key.ports.dport; in bnxt_hwrm_cfa_flow_alloc()
726 req.l4_dst_port_mask = flow->l4_mask.ports.dport; in bnxt_hwrm_cfa_flow_alloc()
727 } else if (flow->flags & BNXT_TC_FLOW_FLAGS_ICMP) { in bnxt_hwrm_cfa_flow_alloc()
729 req.l4_src_port = htons(flow->l4_key.icmp.type); in bnxt_hwrm_cfa_flow_alloc()
730 req.l4_src_port_mask = htons(flow->l4_mask.icmp.type); in bnxt_hwrm_cfa_flow_alloc()
731 req.l4_dst_port = htons(flow->l4_key.icmp.code); in bnxt_hwrm_cfa_flow_alloc()
732 req.l4_dst_port_mask = htons(flow->l4_mask.icmp.code); in bnxt_hwrm_cfa_flow_alloc()
769 * flow handle flow handle in bnxt_hwrm_cfa_flow_alloc()
771 * flow_handle flow handle flow context id in bnxt_hwrm_cfa_flow_alloc()
772 * ext_flow_handle INVALID flow handle in bnxt_hwrm_cfa_flow_alloc()
773 * flow_id INVALID flow counter id in bnxt_hwrm_cfa_flow_alloc()
786 struct bnxt_tc_flow *flow, in hwrm_cfa_decap_filter_alloc() argument
793 struct ip_tunnel_key *tun_key = &flow->tun_key; in hwrm_cfa_decap_filter_alloc()
805 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ID) { in hwrm_cfa_decap_filter_alloc()
811 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS) { in hwrm_cfa_decap_filter_alloc()
823 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS) { in hwrm_cfa_decap_filter_alloc()
832 if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_PORTS) { in hwrm_cfa_decap_filter_alloc()
944 /* remove flow_node from the L2 shared flow list */ in bnxt_tc_put_l2_node()
989 /* Get the ref_flow_handle for a flow by checking if there are any other
990 * flows that share the same L2 key as this flow.
993 bnxt_tc_get_ref_flow_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_get_ref_flow_handle() argument
1003 &flow->l2_key); in bnxt_tc_get_ref_flow_handle()
1007 /* If any other flow is using this l2_node, use it's flow_handle in bnxt_tc_get_ref_flow_handle()
1020 * with a matching l2 key can use the flow_handle of this flow in bnxt_tc_get_ref_flow_handle()
1029 /* After the flow parsing is done, this routine is used for checking
1030 * if there are any aspects of the flow that prevent it from being
1033 static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow) in bnxt_tc_can_offload() argument
1036 if ((flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) && in bnxt_tc_can_offload()
1037 (flow->l4_key.ip_proto != IPPROTO_TCP && in bnxt_tc_can_offload()
1038 flow->l4_key.ip_proto != IPPROTO_UDP)) { in bnxt_tc_can_offload()
1040 flow->l4_key.ip_proto); in bnxt_tc_can_offload()
1045 if (bits_set(&flow->l2_key.smac, sizeof(flow->l2_key.smac)) && in bnxt_tc_can_offload()
1046 !is_exactmatch(flow->l2_mask.smac, sizeof(flow->l2_mask.smac))) { in bnxt_tc_can_offload()
1050 if (bits_set(&flow->l2_key.dmac, sizeof(flow->l2_key.dmac)) && in bnxt_tc_can_offload()
1051 !is_exactmatch(&flow->l2_mask.dmac, sizeof(flow->l2_mask.dmac))) { in bnxt_tc_can_offload()
1057 if (bits_set(&flow->l2_key.inner_vlan_tci, in bnxt_tc_can_offload()
1058 sizeof(flow->l2_key.inner_vlan_tci)) && in bnxt_tc_can_offload()
1059 !is_vlan_tci_allowed(flow->l2_mask.inner_vlan_tci, in bnxt_tc_can_offload()
1060 flow->l2_key.inner_vlan_tci)) { in bnxt_tc_can_offload()
1064 if (bits_set(&flow->l2_key.inner_vlan_tpid, in bnxt_tc_can_offload()
1065 sizeof(flow->l2_key.inner_vlan_tpid)) && in bnxt_tc_can_offload()
1066 !is_exactmatch(&flow->l2_mask.inner_vlan_tpid, in bnxt_tc_can_offload()
1067 sizeof(flow->l2_mask.inner_vlan_tpid))) { in bnxt_tc_can_offload()
1073 if (!is_exactmatch(&flow->l2_mask.ether_type, in bnxt_tc_can_offload()
1074 sizeof(flow->l2_mask.ether_type))) { in bnxt_tc_can_offload()
1142 struct bnxt_tc_flow *flow, in bnxt_tc_get_ref_decap_handle() argument
1157 /* If any other flow is using this decap_l2_node, use it's decap_handle in bnxt_tc_get_ref_decap_handle()
1172 * this flow as their ref_decap_handle in bnxt_tc_get_ref_decap_handle()
1188 /* remove flow_node from the decap L2 sharing flow list */ in bnxt_tc_put_decap_l2_node()
1223 struct flowi4 flow = { {0} }; in bnxt_tc_resolve_tunnel_hdrs() local
1229 flow.flowi4_proto = IPPROTO_UDP; in bnxt_tc_resolve_tunnel_hdrs()
1230 flow.fl4_dport = tun_key->tp_dst; in bnxt_tc_resolve_tunnel_hdrs()
1231 flow.daddr = tun_key->u.ipv4.dst; in bnxt_tc_resolve_tunnel_hdrs()
1233 rt = ip_route_output_key(dev_net(real_dst_dev), &flow); in bnxt_tc_resolve_tunnel_hdrs()
1235 netdev_info(bp->dev, "no route to %pI4b\n", &flow.daddr); in bnxt_tc_resolve_tunnel_hdrs()
1262 netdev_name(dst_dev), &flow.daddr, in bnxt_tc_resolve_tunnel_hdrs()
1268 nbr = dst_neigh_lookup(&rt->dst, &flow.daddr); in bnxt_tc_resolve_tunnel_hdrs()
1271 &flow.daddr); in bnxt_tc_resolve_tunnel_hdrs()
1276 tun_key->u.ipv4.src = flow.saddr; in bnxt_tc_resolve_tunnel_hdrs()
1292 static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_get_decap_handle() argument
1296 struct ip_tunnel_key *decap_key = &flow->tun_key; in bnxt_tc_get_decap_handle()
1305 /* Check if there's another flow using the same tunnel decap. in bnxt_tc_get_decap_handle()
1326 tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src; in bnxt_tc_get_decap_handle()
1327 tun_key.tp_dst = flow->tun_key.tp_dst; in bnxt_tc_get_decap_handle()
1340 flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS; in bnxt_tc_get_decap_handle()
1344 * key and if so, pass that flow's decap_filter_handle as the in bnxt_tc_get_decap_handle()
1345 * ref_decap_handle for this flow. in bnxt_tc_get_decap_handle()
1347 rc = bnxt_tc_get_ref_decap_handle(bp, flow, decap_l2_info, flow_node, in bnxt_tc_get_decap_handle()
1353 rc = hwrm_cfa_decap_filter_alloc(bp, flow, decap_l2_info, in bnxt_tc_get_decap_handle()
1390 static int bnxt_tc_get_encap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_get_encap_handle() argument
1394 struct ip_tunnel_key *encap_key = &flow->actions.tun_encap_key; in bnxt_tc_get_encap_handle()
1399 /* Check if there's another flow using the same tunnel encap. in bnxt_tc_get_encap_handle()
1435 struct bnxt_tc_flow *flow, in bnxt_tc_put_tunnel_handle() argument
1438 if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) in bnxt_tc_put_tunnel_handle()
1440 else if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) in bnxt_tc_put_tunnel_handle()
1445 struct bnxt_tc_flow *flow, in bnxt_tc_get_tunnel_handle() argument
1449 if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) in bnxt_tc_get_tunnel_handle()
1450 return bnxt_tc_get_decap_handle(bp, flow, flow_node, in bnxt_tc_get_tunnel_handle()
1452 else if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) in bnxt_tc_get_tunnel_handle()
1453 return bnxt_tc_get_encap_handle(bp, flow, flow_node, in bnxt_tc_get_tunnel_handle()
1464 /* send HWRM cmd to free the flow-id */ in __bnxt_tc_del_flow()
1470 bnxt_tc_put_tunnel_handle(bp, &flow_node->flow, flow_node); in __bnxt_tc_del_flow()
1487 static void bnxt_tc_set_flow_dir(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_set_flow_dir() argument
1490 flow->l2_key.dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX; in bnxt_tc_set_flow_dir()
1493 static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, in bnxt_tc_set_src_fid() argument
1496 if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) in bnxt_tc_set_src_fid()
1497 flow->src_fid = bp->pf.fw_fid; in bnxt_tc_set_src_fid()
1499 flow->src_fid = src_fid; in bnxt_tc_set_src_fid()
1502 /* Add a new flow or replace an existing flow.
1505 * 1. while adding a new flow
1508 * c) link l2-key with flow
1509 * 2. while deleting a flow
1510 * a) unlinking l2-key from flow
1520 struct bnxt_tc_flow *flow; in bnxt_tc_add_flow() local
1525 /* allocate memory for the new flow and it's node */ in bnxt_tc_add_flow()
1532 flow = &new_node->flow; in bnxt_tc_add_flow()
1534 rc = bnxt_tc_parse_flow(bp, tc_flow_cmd, flow); in bnxt_tc_add_flow()
1538 bnxt_tc_set_src_fid(bp, flow, src_fid); in bnxt_tc_add_flow()
1539 bnxt_tc_set_flow_dir(bp, flow, flow->src_fid); in bnxt_tc_add_flow()
1541 if (!bnxt_tc_can_offload(bp, flow)) { in bnxt_tc_add_flow()
1547 /* If a flow exists with the same cookie, delete it */ in bnxt_tc_add_flow()
1554 /* Check if the L2 part of the flow has been offloaded already. in bnxt_tc_add_flow()
1558 rc = bnxt_tc_get_ref_flow_handle(bp, flow, new_node, &ref_flow_handle); in bnxt_tc_add_flow()
1562 /* If the flow involves tunnel encap/decap, get tunnel_handle */ in bnxt_tc_add_flow()
1563 rc = bnxt_tc_get_tunnel_handle(bp, flow, new_node, &tunnel_handle); in bnxt_tc_add_flow()
1567 /* send HWRM cmd to alloc the flow */ in bnxt_tc_add_flow()
1568 rc = bnxt_hwrm_cfa_flow_alloc(bp, flow, ref_flow_handle, in bnxt_tc_add_flow()
1573 flow->lastused = jiffies; in bnxt_tc_add_flow()
1574 spin_lock_init(&flow->stats_lock); in bnxt_tc_add_flow()
1575 /* add new flow to flow-table */ in bnxt_tc_add_flow()
1587 bnxt_tc_put_tunnel_handle(bp, flow, new_node); in bnxt_tc_add_flow()
1621 struct bnxt_tc_flow *flow; in bnxt_tc_get_flow_stats() local
1630 flow = &flow_node->flow; in bnxt_tc_get_flow_stats()
1631 curr_stats = &flow->stats; in bnxt_tc_get_flow_stats()
1632 prev_stats = &flow->prev_stats; in bnxt_tc_get_flow_stats()
1634 spin_lock(&flow->stats_lock); in bnxt_tc_get_flow_stats()
1638 lastused = flow->lastused; in bnxt_tc_get_flow_stats()
1639 spin_unlock(&flow->stats_lock); in bnxt_tc_get_flow_stats()
1655 /* If flow_id is used to fetch flow stats then: in bnxt_fill_cfa_stats_req()
1657 * 2. 15th bit of flow_handle must specify the flow in bnxt_fill_cfa_stats_req()
1660 if (flow_node->flow.l2_key.dir == BNXT_DIR_RX) in bnxt_fill_cfa_stats_req()
1755 struct bnxt_tc_flow *flow = &flow_node->flow; in bnxt_tc_flow_stats_batch_update() local
1757 spin_lock(&flow->stats_lock); in bnxt_tc_flow_stats_batch_update()
1758 bnxt_flow_stats_accum(tc_info, &flow->stats, in bnxt_tc_flow_stats_batch_update()
1760 if (flow->stats.packets != flow->prev_stats.packets) in bnxt_tc_flow_stats_batch_update()
1761 flow->lastused = jiffies; in bnxt_tc_flow_stats_batch_update()
1762 spin_unlock(&flow->stats_lock); in bnxt_tc_flow_stats_batch_update()