Skip to content
  • Thomas Haller's avatar
    platform: fix handling of default value for TCA_FQ_CODEL_CE_THRESHOLD · 859f8479
    Thomas Haller authored and Lubomir Rintel's avatar Lubomir Rintel committed
    iproute2 uses the special value ~0u to indicate not to set
    TCA_FQ_CODEL_CE_THRESHOLD in RTM_NEWQDISC. When not explicitly
    setting the value, kernel treats the threshold as disabled.
    
    However note that 0xFFFFFFFFu is not an invalid threshold (as far as
    kernel is concerned). Thus, we should not use that as value to indicate
    that the value is unset. Note that iproute2 uses the special value ~0u
    only internally thereby making it impossible to set the threshold to
    0xFFFFFFFFu). But kernel does not have this limitation.
    
    Maybe the cleanest way would be to add another field to NMPlatformQDisc:
    
        guint32 ce_threshold;
        bool ce_threshold_set:1;
    
    that indicates whether the threshold is enable or not.
    But note that kernel does:
    
        static void codel_params_init(struct codel_params *params)
        {
        ...
                params->ce_threshold = CODEL_DISABLED_THRESHOLD;
    
        static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
                                   struct netlink_ext_ack *extack)
        {
        ...
                if (tb[TCA_FQ_CODEL_CE_THRESHOLD]) {
                        u64 val = nla_get_u32(tb[TCA_FQ_CODEL_CE_THRESHOLD]);
    
                        q->cparams.ce_threshold = (val * NSEC_PER_USEC) >> CODEL_SHIFT;
                }
    
        static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb)
        {
        ...
                if (q->cparams.ce_threshold != CODEL_DISABLED_THRESHOLD &&
                    nla_put_u32(skb, TCA_FQ_CODEL_CE_THRESHOLD,
                                codel_time_to_us(q->cparams.ce_threshold)))
                        goto nla_put_failure;
    
    This means, kernel internally uses the special value 0x83126E97u to indicate
    that the threshold is disabled (WTF). That is because
    
      (((guint64) 0x83126E97u) * NSEC_PER_USEC) >> CODEL_SHIFT == CODEL_DISABLED_THRESHOLD
    
    So in kernel API this value is reserved (and has a special meaning
    to indicate that the threshold is disabled). So, instead of adding a
    ce_threshold_set flag, use the same value that kernel anyway uses.
    
    (cherry picked from commit 973db2d4)
    859f8479