]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixed various build problems on FreeBSD and/or CLang
authorMaria Matejka <mq@ucw.cz>
Fri, 20 Jan 2023 13:07:38 +0000 (14:07 +0100)
committerMaria Matejka <mq@ucw.cz>
Fri, 20 Jan 2023 17:31:57 +0000 (18:31 +0100)
filter/config.Y
lib/birdlib.h
lib/settle.h
nest/rt-table.c
sysdep/bsd/krt-sock.c
sysdep/linux/netlink.Y
sysdep/unix/domain.c
sysdep/unix/krt.c

index d20e4a0492bc0214639e66c45a14de2b1057cf1d..7f1526593e77e5b4587f4a0b39e0f2151e7b7e83 100644 (file)
@@ -338,7 +338,6 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
 %type <xp> cmds_int cmd_prep
 %type <x> term cmd cmd_var cmds cmds_scoped constant constructor print_list var var_init var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
 %type <fsa> static_attr
-%type <fab> attr_bit
 %type <f> filter where_filter
 %type <fl> filter_body function_body
 %type <flv> lvalue
@@ -846,10 +845,6 @@ term:
  | constructor { $$ = $1; }
 
  | static_attr { $$ = f_new_inst(FI_RTA_GET, $1); }
- | attr_bit {
-    struct f_inst *c = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)});
-    $$ = f_new_inst(FI_EQ, c, f_new_inst(FI_BITAND, f_new_inst(FI_EA_GET, $1.class), c));
-  }
 
  | term '.' IS_V4 { $$ = f_new_inst(FI_IS_V4, $1); }
  | term '.' TYPE { $$ = f_new_inst(FI_TYPE, $1); }
@@ -979,14 +974,6 @@ cmd:
        cf_error("Attribute %s is read-only", $3->attribute->name);
      $$ = f_new_inst(FI_EA_UNSET, $3->attribute);
    }
- | attr_bit '=' term ';' {
-     $$ = f_new_inst(FI_CONDITION, $3,
-       f_generate_complex_default(FI_BITOR, $1.class,
-             f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)}), 0),
-       f_generate_complex_default(FI_BITAND, $1.class,
-             f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = ~(1U << $1.bit)}), 0)
-     );
-   }
  | break_command print_list ';' {
     struct f_inst *breaker = f_new_inst(FI_DIE, $1);
     if ($2) {
index d743ecdf0532141ccbf26f3c95faea04b60715ee..5ecd19ca08a813435ce6ab4f9a1989ebc81abec3 100644 (file)
@@ -9,13 +9,22 @@
 #ifndef _BIRD_BIRDLIB_H_
 #define _BIRD_BIRDLIB_H_
 
+#include <stddef.h>
+
 #include "sysdep/config.h"
 #include "lib/alloca.h"
 
 /* Ugly structure offset handling macros */
 
 #define SAME_TYPE(a, b)        ({ int _ = ((a) != (b)); !_; })
+#define TYPE_CAST(from, to, what) ( SAME_TYPE(((from) NULL), (what)), ((to) (what)))
+
+#ifdef offsetof
+#define OFFSETOF offsetof
+#else
 #define OFFSETOF(s, i) ((size_t) &((s *)0)->i)
+#endif
+
 #define SKIP_BACK(s, i, p) ({ s *_ptr = ((s *)((char *)p - OFFSETOF(s, i))); SAME_TYPE(&_ptr->i, p); _ptr; })
 #define BIRD_ALIGN(s, a) (((s)+a-1)&~(a-1))
 #define CPU_STRUCT_ALIGN  (MAX_(_Alignof(void*), _Alignof(u64)))
index d274599d8e1b2106d21a447dd3e977c3ffba66e4..e721f21f1499d337e25e37ced3cc5ef8dedd10b5 100644 (file)
@@ -32,7 +32,7 @@ struct settle {
 
 STATIC_ASSERT(OFFSETOF(struct settle, hook) == OFFSETOF(struct settle, tm) + OFFSETOF(timer, hook));
 
-#define SETTLE_INIT(_cfp, _hook, _data) (struct settle) { .tm = { .data = (_data), }, .hook = (_hook), .cf = ({ASSERT_DIE((_cfp)->min <= (_cfp)->max); *(_cfp); }), }
+#define SETTLE_INIT(_cfp, _hook, _data) (struct settle) { .tm = { .data = (_data), .hook = TYPE_CAST(void (*)(struct settle *), void (*)(struct timer *), (_hook)), }, .cf = ({ASSERT_DIE((_cfp)->min <= (_cfp)->max); *(_cfp); }), }
 
 
 static inline void settle_init(struct settle *s, struct settle_config *cf, void (*hook)(struct settle *), void *data)
index e712796bde5f71a20d1b3e17153e5f86db1759e2..48f5587b771266992605513204f7a7a172069b6f 100644 (file)
@@ -3352,8 +3352,8 @@ ea_set_hostentry(ea_list **to, rtable *dep, rtable *src, ip_addr gw, ip_addr ll,
   struct {
     struct adata ad;
     struct hostentry *he;
-    u32 labels[lnum];
-  } *head = (void *) tmp_alloc_adata(sizeof *head - sizeof(struct adata));
+    u32 labels[0];
+  } *head = (void *) tmp_alloc_adata(sizeof *head + sizeof(u32) * lnum - sizeof(struct adata));
 
   RT_LOCKED(src, tab)
     head->he = rt_get_hostentry(tab, gw, ll, dep);
index 1c1bd50cac3936f86bef4f4f0e97f3552d783fc7..0706f546c26f6fc45a3ce13526f5a17403e11665 100644 (file)
@@ -148,15 +148,18 @@ static struct krt_proto *krt_table_map[KRT_MAX_TABLES][2];
 int
 krt_capable(rte *e)
 {
-  rta *a = e->attrs;
+  ea_list *eattrs = e->attrs;
+  eattr *nhea = ea_find(eattrs, &ea_gen_nexthop);
+  struct nexthop_adata *nh = nhea ? (struct nexthop_adata *) nhea->u.ptr : NULL;
+  int dest = nhea_dest(nhea);
 
   return
-    ((a->dest == RTD_UNICAST && !a->nh.next) /* No multipath support */
+    ((dest == RTD_UNICAST && !NEXTHOP_ONE(nh)) /* No multipath support */
 #ifdef RTF_REJECT
-     || a->dest == RTD_UNREACHABLE
+     || dest == RTD_UNREACHABLE
 #endif
 #ifdef RTF_BLACKHOLE
-     || a->dest == RTD_BLACKHOLE
+     || dest == RTD_BLACKHOLE
 #endif
      );
 }
@@ -197,18 +200,22 @@ sockaddr_fill_dl(struct sockaddr_dl *sa, struct iface *ifa)
 }
 
 static int
-krt_send_route(struct krt_proto *p, int cmd, rte *e)
+krt_send_route(struct krt_proto *p, int cmd, const rte *e)
 {
-  net *net = e->net;
-  rta *a = e->attrs;
+  const net_addr *net = e->net;
+  ea_list *eattrs = e->attrs;
+  eattr *nhea = ea_find(eattrs, &ea_gen_nexthop);
+  struct nexthop_adata *nh = nhea ? (struct nexthop_adata *) nhea->u.ptr : NULL;
+  int dest = nhea_dest(nhea);
+
   static int msg_seq;
-  struct iface *j, *i = a->nh.iface;
+  struct iface *j, *i = (dest == RTD_UNICAST) ? nh->nh.iface : NULL;
   int l;
   struct ks_msg msg;
   char *body = (char *)msg.buf;
   sockaddr gate, mask, dst;
 
-  DBG("krt-sock: send %I/%d via %I\n", net->n.prefix, net->n.pxlen, a->gw);
+  DBG("krt-sock: send %N via %I\n", net, nh->nh.gw);
 
   bzero(&msg,sizeof (struct rt_msghdr));
   msg.rtm.rtm_version = RTM_VERSION;
@@ -218,7 +225,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
   msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1;
 
   /* XXXX */
-  if (net_pxlen(net->n.addr) == net_max_prefix_length[net->n.addr->type])
+  if (net_pxlen(e->net) == net_max_prefix_length[net->type])
     msg.rtm.rtm_flags |= RTF_HOST;
   else
     msg.rtm.rtm_addrs |= RTA_NETMASK;
@@ -228,11 +235,11 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
 #endif
 
 #ifdef RTF_REJECT
-  if(a->dest == RTD_UNREACHABLE)
+  if(dest == RTD_UNREACHABLE)
     msg.rtm.rtm_flags |= RTF_REJECT;
 #endif
 #ifdef RTF_BLACKHOLE
-  if(a->dest == RTD_BLACKHOLE)
+  if(dest == RTD_BLACKHOLE)
     msg.rtm.rtm_flags |= RTF_BLACKHOLE;
 #endif
 
@@ -260,7 +267,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
 
   int af = AF_UNSPEC;
 
-  switch (net->n.addr->type) {
+  switch (net->type) {
     case NET_IP4:
       af = AF_INET;
       break;
@@ -268,19 +275,19 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
       af = AF_INET6;
       break;
     default:
-      log(L_ERR "KRT: Not sending route %N to kernel", net->n.addr);
+      log(L_ERR "KRT: Not sending route %N to kernel", net);
       return -1;
   }
 
-  sockaddr_fill(&dst,  af, net_prefix(net->n.addr), NULL, 0);
-  sockaddr_fill(&mask, af, net_pxmask(net->n.addr), NULL, 0);
+  sockaddr_fill(&dst,  af, net_prefix(net), NULL, 0);
+  sockaddr_fill(&mask, af, net_pxmask(net), NULL, 0);
 
-  switch (a->dest)
+  switch (dest)
   {
   case RTD_UNICAST:
-    if (ipa_nonzero(a->nh.gw))
+    if (ipa_nonzero(nh->nh.gw))
     {
-      ip_addr gw = a->nh.gw;
+      ip_addr gw = nh->nh.gw;
 
       /* Embed interface ID to link-local address */
       if (ipa_is_link_local(gw))
@@ -292,6 +299,8 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
       break;
     }
 
+    /* Fall through */
+
 #ifdef RTF_REJECT
   case RTD_UNREACHABLE:
 #endif
@@ -303,7 +312,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
 
 #if __OpenBSD__
     /* Keeping temporarily old code for OpenBSD */
-    struct ifa *addr = (net->n.addr->type == NET_IP4) ? i->addr4 : (i->addr6 ?: i->llv6);
+    struct ifa *addr = (net->type == NET_IP4) ? i->addr4 : (i->addr6 ?: i->llv6);
 
     if (!addr)
     {
@@ -339,7 +348,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
   msg.rtm.rtm_msglen = l;
 
   if ((l = write(p->sys.sk->fd, (char *)&msg, l)) < 0) {
-    log(L_ERR "KRT: Error sending route %N to kernel: %m", net->n.addr);
+    log(L_ERR "KRT: Error sending route %N to kernel: %m", net);
     return -1;
   }
 
@@ -347,7 +356,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
 }
 
 void
-krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old)
+krt_replace_rte(struct krt_proto *p, const net_addr *n UNUSED, rte *new, const rte *old)
 {
   int err = 0;
 
@@ -398,7 +407,6 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
   /* p is NULL iff KRT_SHARED_SOCKET and !scan */
 
   int ipv6;
-  net *net;
   sockaddr dst, gate, mask;
   ip_addr idst, igate, imask;
   net_addr ndst;
@@ -514,74 +522,82 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
     src = KRT_SRC_ALIEN;
   else
     src = KRT_SRC_KERNEL;
+  
+  union {
+    struct {
+      struct adata ad;
+      struct nexthop nh;
+      u32 labels[MPLS_MAX_LABEL_STACK];
+    };
+    struct nexthop_adata nhad;
+  } nhad = {};
 
-  net = net_get(p->p.main_channel->table, &ndst);
-
-  rta a = {
-  };
+  ea_list *eattrs = NULL;
 
-  ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_INHERIT);
+  ea_set_attr_u32(&eattrs, &ea_gen_source, 0, RTS_INHERIT);
 
   /* reject/blackhole routes have also set RTF_GATEWAY,
      we wil check them first. */
 
 #ifdef RTF_REJECT
   if(flags & RTF_REJECT) {
-    a.dest = RTD_UNREACHABLE;
+    nhad.nhad = NEXTHOP_DEST_LITERAL(RTD_UNREACHABLE);
     goto done;
   }
 #endif
 
 #ifdef RTF_BLACKHOLE
   if(flags & RTF_BLACKHOLE) {
-    a.dest = RTD_BLACKHOLE;
+    nhad.nhad = NEXTHOP_DEST_LITERAL(RTD_BLACKHOLE);
     goto done;
   }
 #endif
 
-  a.nh.iface = if_find_by_index(msg->rtm.rtm_index);
-  if (!a.nh.iface)
+  nhad.nh.iface = if_find_by_index(msg->rtm.rtm_index);
+  if (!nhad.nh.iface)
     {
       log(L_ERR "KRT: Received route %N with unknown ifindex %u",
-         net->n.addr, msg->rtm.rtm_index);
+         &ndst, msg->rtm.rtm_index);
       return;
     }
 
-  a.dest = RTD_UNICAST;
   if (flags & RTF_GATEWAY)
   {
-    a.nh.gw = igate;
+    nhad.nh.gw = igate;
 
     /* Clean up embedded interface ID returned in link-local address */
-    if (ipa_is_link_local(a.nh.gw))
-      _I0(a.nh.gw) = 0xfe800000;
+    if (ipa_is_link_local(nhad.nh.gw))
+      _I0(nhad.nh.gw) = 0xfe800000;
 
     /* The BSD kernel does not support an onlink flag. We heuristically
        set the onlink flag, if the iface has only host addresses. */
-    if (krt_assume_onlink(a.nh.iface, ipv6))
-      a.nh.flags |= RNF_ONLINK;
+    if (krt_assume_onlink(nhad.nh.iface, ipv6))
+      nhad.nh.flags |= RNF_ONLINK;
 
     neighbor *nbr;
-    nbr = neigh_find(&p->p, a.nh.gw, a.nh.iface,
-                   (a.nh.flags & RNF_ONLINK) ? NEF_ONLINK : 0);
+    nbr = neigh_find(&p->p, nhad.nh.gw, nhad.nh.iface,
+                   (nhad.nh.flags & RNF_ONLINK) ? NEF_ONLINK : 0);
     if (!nbr || (nbr->scope == SCOPE_HOST))
       {
        /* Ignore routes with next-hop 127.0.0.1, host routes with such
           next-hop appear on OpenBSD for address aliases. */
-        if (ipa_classify(a.nh.gw) == (IADDR_HOST | SCOPE_HOST))
+        if (ipa_classify(nhad.nh.gw) == (IADDR_HOST | SCOPE_HOST))
           return;
 
        log(L_ERR "KRT: Received route %N with strange next-hop %I",
-           net->n.addr, a.nh.gw);
+           &ndst, nhad.nh.gw);
        return;
       }
   }
 
- done:;
-  rte e0 = { .attrs = &a, .net = net, };
+  nhad.ad.length = (void *) NEXTHOP_NEXT(&nhad.nh) - (void *) nhad.ad.data;
+
+ done:
+  ea_set_attr(&eattrs, EA_LITERAL_DIRECT_ADATA(&ea_gen_nexthop, 0, &nhad.ad));
+  rte e0 = { .attrs = eattrs, .net = &ndst, };
 
-  ea_set_attr(e0.attrs->eattrs,
-      EA_LITERAL_EMBEDDED(EA_KRT_SOURCE, T_INT, 0, src2));
+  ea_set_attr(&e0.attrs,
+      EA_LITERAL_EMBEDDED(&ea_krt_source, 0, src2));
 
   if (scan)
     krt_got_route(p, &e0, src);
@@ -822,6 +838,7 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
   {
     case RTM_GET:
       if(!scan) return;
+      /* Fall through */
     case RTM_ADD:
     case RTM_DELETE:
     case RTM_CHANGE:
index 7ba8c7c90edd3290a36a6bcf72e2a1653616ae57..9b07e9bb76dfc5d1c9ffd8aa7baf5e2e4e200ee0 100644 (file)
@@ -15,6 +15,8 @@ CF_KEYWORDS(KERNEL, TABLE, METRIC, NETLINK, RX, BUFFER,
            KRT_LOCK_SSTRESH, KRT_LOCK_CWND, KRT_LOCK_ADVMSS, KRT_LOCK_REORDERING,
            KRT_LOCK_HOPLIMIT, KRT_LOCK_RTO_MIN, KRT_FEATURE_ECN, KRT_FEATURE_ALLFRAG)
 
+%type <fab> attr_bit
+
 CF_GRAMMAR
 
 kern_proto: kern_proto kern_sys_item ';' ;
@@ -42,6 +44,25 @@ attr_bit: KRT_LOCK_RTO_MIN { $$ = f_new_dynamic_attr_bit(13, "krt_lock"); } ;
 attr_bit: KRT_FEATURE_ECN      { $$ = f_new_dynamic_attr_bit(0, "krt_features"); } ;
 attr_bit: KRT_FEATURE_ALLFRAG { $$ = f_new_dynamic_attr_bit(3, "krt_features"); } ;
 
+/* Getting attribute bits (moved here to not confuse Bison on *BSD) */
+term:
+   attr_bit {
+    struct f_inst *c = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)});
+    $$ = f_new_inst(FI_EQ, c, f_new_inst(FI_BITAND, f_new_inst(FI_EA_GET, $1.class), c));
+  }
+ ;
+
+/* Setting attribute bits (moved here to not confuse Bison on *BSD) */
+cmd:
+   attr_bit '=' term ';' {
+     $$ = f_new_inst(FI_CONDITION, $3,
+       f_generate_complex_default(FI_BITOR, $1.class,
+             f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)}), 0),
+       f_generate_complex_default(FI_BITAND, $1.class,
+             f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = ~(1U << $1.bit)}), 0)
+     );
+   }
+ ;
 
 CF_CODE
 
index 1cba540b05e4d5c7e7f4800369c2e4fb87933bde..f4ee595df9dd12861de054af1f8a895a2bb23e51 100644 (file)
@@ -83,11 +83,15 @@ uint dg_order(struct domain_generic *dg)
 
 void do_lock(struct domain_generic *dg, struct domain_generic **lsp)
 {
+  struct lock_order stack_copy;
+  memcpy(&stack_copy, &locking_stack, sizeof(stack_copy));
+  struct domain_generic **lll = last_locked;
+
   if ((char *) lsp - (char *) &locking_stack != dg->order)
     bug("Trying to lock on bad position: order=%u, lsp=%p, base=%p", dg->order, lsp, &locking_stack);
 
   if (lsp <= last_locked)
-    bug("Trying to lock in a bad order");
+    bug("Trying to lock in a bad order: %p %p", &stack_copy, lll);
   if (*lsp)
     bug("Inconsistent locking stack state on lock");
 
index 3b6c91cc9a4a3393225ef51b90b2a90b1894c014..b3681c9c6c72c76a286371b47d5a24d3f4f1351a 100644 (file)
@@ -290,18 +290,6 @@ krt_metric(rte *a)
   return ea ? ea->u.data : 0;
 }
 
-static inline int
-krt_same_key(rte *a, rte *b)
-{
-  return (krt_metric(a) == krt_metric(b));
-}
-
-static inline int
-krt_uptodate(rte *a, rte *b)
-{
-  return (a->attrs == b->attrs);
-}
-
 static void
 krt_learn_alien_attr(struct channel *c, rte *e)
 {
@@ -444,10 +432,13 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src)
   switch (src)
     {
     case KRT_SRC_KERNEL:
-      goto ignore;
+      krt_trace_in(p, e, "ignored");
+      return;
 
     case KRT_SRC_REDIRECT:
-      goto delete;
+      krt_trace_in(p, e, "deleting");
+      krt_replace_rte(p, e->net, NULL, e);
+      return;
 
     case  KRT_SRC_ALIEN:
       if (KRT_CF->learn)
@@ -457,6 +448,7 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src)
       return;
     }
 #endif
+
   /* The rest is for KRT_SRC_BIRD (or KRT_SRC_UNKNOWN) */
 
   RT_LOCKED(p->p.main_channel->table, tab)
@@ -719,7 +711,11 @@ static int
 krt_preexport(struct channel *C, rte *e)
 {
   if (e->src->owner == &C->proto->sources)
+#ifdef CONFIG_SINGLE_ROUTE
+    return 1;
+#else
     return -1;
+#endif
 
   if (!krt_capable(e))
     return -1;
@@ -737,14 +733,8 @@ krt_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *net,
     return;
 
 #ifdef CONFIG_SINGLE_ROUTE
-  /*
-   * Implicit withdraw - when the imported kernel route becomes the best one,
-   * we know that the previous one exported to the kernel was already removed,
-   * but if we processed the update as usual, we would send withdraw to the
-   * kernel, which would remove the new imported route instead.
-   */
-  rte *best = net->routes;
-  if (!new && best && (best->attrs->src->proto == P))
+  /* Got the same route as we imported. Keep it, do nothing. */
+  if (new && new->src->owner == &P->sources)
     return;
 #endif