I was having a look at cake's hash code and it seems srchost_hash and dsthost_hash, as well as the flowkeys in NAT are not calculated in plain "srchost" or "dsthost" modes. CAKE_FLOW_FLOWS and CAKE_FLOW_HOSTS are both 0 (conditional in line 633) when src/dst-host is set as flow mode. So the code goes to "skip_hash" (line 683), and as a result the flowkeys are not updated in respect to NAT (line 640), but also srchost_hash and dsthost_hash (line 653) are not calculated.
Is this intentional? I would expect the NAT flowkeys to be updated in src/dst-host modes, and also the host hashes to be calculated for fair host isolation. cake_hash() in sch_cake.c from linux-4.20: 632 /* If both overrides are set we can skip packet dissection entirely */ 633 if ((flow_override || !(flow_mode & CAKE_FLOW_FLOWS)) && 634 (host_override || !(flow_mode & CAKE_FLOW_HOSTS))) 635 goto skip_hash; 636 637 skb_flow_dissect_flow_keys(skb, &keys, 638 FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); 639 640 if (flow_mode & CAKE_FLOW_NAT_FLAG) 641 cake_update_flowkeys(&keys, skb); 642 643 /* flow_hash_from_keys() sorts the addresses by value, so we have 644 * to preserve their order in a separate data structure to treat 645 * src and dst host addresses as independently selectable. 646 */ 647 host_keys = keys; 648 host_keys.ports.ports = 0; 649 host_keys.basic.ip_proto = 0; 650 host_keys.keyid.keyid = 0; 651 host_keys.tags.flow_label = 0; 652 653 switch (host_keys.control.addr_type) { 654 case FLOW_DISSECTOR_KEY_IPV4_ADDRS: 655 host_keys.addrs.v4addrs.src = 0; 656 dsthost_hash = flow_hash_from_keys(&host_keys); 657 host_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src; 658 host_keys.addrs.v4addrs.dst = 0; 659 srchost_hash = flow_hash_from_keys(&host_keys); 660 break; 661 662 case FLOW_DISSECTOR_KEY_IPV6_ADDRS: 663 memset(&host_keys.addrs.v6addrs.src, 0, 664 sizeof(host_keys.addrs.v6addrs.src)); 665 dsthost_hash = flow_hash_from_keys(&host_keys); 666 host_keys.addrs.v6addrs.src = keys.addrs.v6addrs.src; 667 memset(&host_keys.addrs.v6addrs.dst, 0, 668 sizeof(host_keys.addrs.v6addrs.dst)); 669 srchost_hash = flow_hash_from_keys(&host_keys); 670 break; 671 672 default: 673 dsthost_hash = 0; 674 srchost_hash = 0; 675 } 676 677 /* This *must* be after the above switch, since as a 678 * side-effect it sorts the src and dst addresses. 679 */ 680 if (flow_mode & CAKE_FLOW_FLOWS) 681 flow_hash = flow_hash_from_keys(&keys); 682 683 skip_hash: 684 if (flow_override) 685 flow_hash = flow_override - 1; 686 if (host_override) { 687 dsthost_hash = host_override - 1; 688 srchost_hash = host_override - 1; 689 } 690 691 if (!(flow_mode & CAKE_FLOW_FLOWS)) { 692 if (flow_mode & CAKE_FLOW_SRC_IP) 693 flow_hash ^= srchost_hash; 694 695 if (flow_mode & CAKE_FLOW_DST_IP) 696 flow_hash ^= dsthost_hash; 697 } 698 699 reduced_hash = flow_hash % CAKE_QUEUES; _______________________________________________ Cake mailing list Cake@lists.bufferbloat.net https://lists.bufferbloat.net/listinfo/cake