]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit '225943eaea3cdd634dce8fd84547baf1bc363640' into thread-next
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 28 Mar 2024 16:46:04 +0000 (17:46 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 28 Mar 2024 16:46:04 +0000 (17:46 +0100)
1  2 
doc/bird.sgml
sysdep/linux/netlink.c

diff --cc doc/bird.sgml
Simple merge
index 1145cf73229e0b2ab3581f8959cb90cdfd9cff6a,fb54de391468f3b958f444c0222425e5b326621d..06a6ea72c50a9f918cd67ca0b80d818a6e2be786
@@@ -43,101 -42,6 +43,106 @@@ struct nl_parse_stat
    u32 rta_flow;
  };
  
-   "reordering", "hoplimit", "initcwnd", "features", "rto_min", "initrwnd", "quickack"
 +/*
 + *    Netlink eattr definitions
 + */
 +
 +#define KRT_METRICS_MAX               ARRAY_SIZE(ea_krt_metrics)
 +#define KRT_FEATURES_MAX      4
 +
 +static void krt_bitfield_format(const eattr *e, byte *buf, uint buflen);
 +
 +static struct ea_class
 +  ea_krt_prefsrc = {
 +    .name = "krt_prefsrc",
 +    .type = T_IP,
 +  },
 +  ea_krt_realm = {
 +    .name = "krt_realm",
 +    .type = T_INT,
 +  },
 +  ea_krt_scope = {
 +    .name = "krt_scope",
 +    .type = T_INT,
 +  };
 +
 +static struct ea_class ea_krt_metrics[] = {
 +  [RTAX_LOCK] = {
 +    .name = "krt_lock",
 +    .type = T_INT,
 +    .format = krt_bitfield_format,
 +  },
 +  [RTAX_FEATURES] = {
 +    .name = "krt_features",
 +    .type = T_INT,
 +    .format = krt_bitfield_format,
 +  },
++  [RTAX_CC_ALGO] = {
++    .name = "krt_congctl",
++    .type = T_STRING,
++  },
 +#define KRT_METRIC_INT(_rtax, _name)  [_rtax] = { .name = _name, .type = T_INT }
 +  KRT_METRIC_INT(RTAX_MTU, "krt_mtu"),
 +  KRT_METRIC_INT(RTAX_WINDOW, "krt_window"),
 +  KRT_METRIC_INT(RTAX_RTT, "krt_rtt"),
 +  KRT_METRIC_INT(RTAX_RTTVAR, "krt_rttvar"),
 +  KRT_METRIC_INT(RTAX_SSTHRESH, "krt_sstresh"),
 +  KRT_METRIC_INT(RTAX_CWND, "krt_cwnd"),
 +  KRT_METRIC_INT(RTAX_ADVMSS, "krt_advmss"),
 +  KRT_METRIC_INT(RTAX_REORDERING, "krt_reordering"),
 +  KRT_METRIC_INT(RTAX_HOPLIMIT, "krt_hoplimit"),
 +  KRT_METRIC_INT(RTAX_INITCWND, "krt_initcwnd"),
 +  KRT_METRIC_INT(RTAX_RTO_MIN, "krt_rto_min"),
 +  KRT_METRIC_INT(RTAX_INITRWND, "krt_initrwnd"),
 +  KRT_METRIC_INT(RTAX_QUICKACK, "krt_quickack"),
 +#undef KRT_METRIC_INT
 +};
 +
 +static const char *krt_metrics_names[KRT_METRICS_MAX] = {
 +  NULL, "lock", "mtu", "window", "rtt", "rttvar", "sstresh", "cwnd", "advmss",
++  "reordering", "hoplimit", "initcwnd", "features", "rto_min", "initrwnd", "quickack",
++  "congctl"
 +};
 +
 +static const char *krt_features_names[KRT_FEATURES_MAX] = {
 +  "ecn", NULL, NULL, "allfrag"
 +};
 +
 +static void
 +krt_bitfield_format(const eattr *a, byte *buf, uint buflen)
 +{
 +  if (a->id == ea_krt_metrics[RTAX_LOCK].id)
 +    ea_format_bitfield(a, buf, buflen, krt_metrics_names, 2, KRT_METRICS_MAX);
 +  else if (a->id == ea_krt_metrics[RTAX_FEATURES].id)
 +    ea_format_bitfield(a, buf, buflen, krt_features_names, 0, KRT_FEATURES_MAX);
 +}
 +
 +static void
 +nl_ea_register(void)
 +{
 +  EA_REGISTER_ALL(
 +      &ea_krt_prefsrc,
 +      &ea_krt_realm,
 +      &ea_krt_scope
 +      );
 +
 +  for (uint i = 0; i < KRT_METRICS_MAX; i++)
 +  {
 +    if (!ea_krt_metrics[i].name)
 +      ea_krt_metrics[i] = (struct ea_class) {
 +      .name = mb_sprintf(&root_pool, "krt_metric_%d", i),
 +      .type = T_INT,
 +      };
 +
 +    ea_register_init(&ea_krt_metrics[i]);
 +  }
 +
 +  for (uint i = 1; i < KRT_METRICS_MAX; i++)
 +    ASSERT_DIE(ea_krt_metrics[i].id == ea_krt_metrics[0].id + i);
 +}
 +
 +
 +
  /*
   *    Synchronous Netlink interface
   */
@@@ -929,8 -831,10 +943,8 @@@ err
    return NULL;
  }
  
 -STATIC_ASSERT(EA_KRT_METRICS + RTAX_CC_ALGO == EA_KRT_CONGCTL);
 -
  static void
- nl_add_metrics(struct nlmsghdr *h, uint bufsize, u32 *metrics, int max)
+ nl_add_metrics(struct nlmsghdr *h, uint bufsize, u32 *metrics, const char *cc_algo, int max)
  {
    struct rtattr *a = nl_open_attr(h, bufsize, RTA_METRICS);
    int t;
@@@ -1498,17 -1414,21 +1530,21 @@@ nl_send_route(struct krt_proto *p, cons
    metrics[0] = 0;
  
    struct ea_walk_state ews = { .eattrs = eattrs };
 -  while (ea = ea_walk(&ews, EA_KRT_METRICS, KRT_METRICS_MAX))
 +  while (ea = ea_walk(&ews, ea_krt_metrics[0].id, KRT_METRICS_MAX))
    {
 -    int id = ea->id - EA_KRT_METRICS;
 +    int id = ea->id - ea_krt_metrics[0].id;
      metrics[0] |= 1 << id;
-     metrics[id] = ea->u.data;
+     if (id == RTAX_CC_ALGO)
+       cc_algo = ea->u.ptr->data;
+     else
+       metrics[id] = ea->u.data;
    }
  
    if (metrics[0])
-     nl_add_metrics(&r->h, rsize, metrics, KRT_METRICS_MAX);
+     nl_add_metrics(&r->h, rsize, metrics, cc_algo, KRT_METRICS_MAX);
  
 -  switch (a->dest)
 +  switch (dest)
      {
      case RTD_UNICAST:
        r->r.rtm_type = RTN_UNICAST;
@@@ -1868,27 -1828,54 +1904,31 @@@ nl_parse_route(struct nl_parse_state *s
    if (a[RTA_METRICS])
      {
        u32 metrics[KRT_METRICS_MAX];
-       if (nl_parse_metrics(a[RTA_METRICS], metrics, ARRAY_SIZE(metrics)) < 0)
+       const char *cc_algo = NULL;
 -      ea_list *ea = lp_alloc(s->pool, sizeof(ea_list) + KRT_METRICS_MAX * sizeof(eattr));
 -      int t, n = 0;
+       if (nl_parse_metrics(a[RTA_METRICS], metrics, &cc_algo, ARRAY_SIZE(metrics)) < 0)
          {
 -        log(L_ERR "KRT: Received route %N with strange RTA_METRICS attribute", net->n.addr);
 +        log(L_ERR "KRT: Received route %N with strange RTA_METRICS attribute", net);
          return;
        }
  
 -      for (t = 1; t < KRT_METRICS_MAX; t++)
 +      for (uint t = 1; t < KRT_METRICS_MAX; t++)
        if (metrics[0] & (1 << t))
-         ea_set_attr(&ra,
-             EA_LITERAL_EMBEDDED(&ea_krt_metrics[t], 0, metrics[t]));
+         if (t == RTAX_CC_ALGO)
 -          {
 -            struct adata *ad = lp_alloc_adata(s->pool, strlen(cc_algo));
 -            memcpy(ad->data, cc_algo, ad->length);
 -
 -            ea->attrs[n++] = (eattr) {
 -              .id = EA_KRT_CONGCTL,
 -              .type = EAF_TYPE_STRING,
 -              .u.ptr = ad,
 -            };
 -          }
++          ea_set_attr(&ra, EA_LITERAL_STORE_ADATA(&ea_krt_metrics[t], 0, cc_algo, strlen(cc_algo)));
+         else
 -          {
 -            ea->attrs[n++] = (eattr) {
 -              .id = EA_KRT_METRICS + t,
 -              .type = EAF_TYPE_INT,   /* FIXME: Some are EAF_TYPE_BITFIELD */
 -              .u.data = metrics[t],
 -            };
 -          }
 -
 -      if (n > 0)
 -        {
 -        ea->next = ra->eattrs;
 -        ea->flags = EALF_SORTED;
 -        ea->count = n;
 -        ra->eattrs = ea;
 -      }
++          ea_set_attr(&ra, EA_LITERAL_EMBEDDED(&ea_krt_metrics[t], 0, metrics[t]));
      }
  
 -  rte *e = rte_get_temp(ra, p->p.main_source);
 -  e->net = net;
 +  rte e0 = {
 +    .net = net,
 +    .attrs = ra,
 +  };
  
    if (s->scan)
 -    krt_got_route(p, e, krt_src);
 +    krt_got_route(p, &e0, krt_src);
    else
 -    krt_got_route_async(p, e, new, krt_src);
 +    krt_got_route_async(p, &e0, new, krt_src);
  
    lp_flush(s->pool);
  }