]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Portability: Fixed C extension error generated by CLang.
authorJan Moskyto Matejka <mq@ucw.cz>
Wed, 27 Apr 2016 12:45:14 +0000 (14:45 +0200)
committerJan Moskyto Matejka <mq@ucw.cz>
Tue, 10 May 2016 12:08:49 +0000 (14:08 +0200)
sysdep/linux/netlink.c:921:10: error: fields must have a constant size:
'variable length array in structure' extension will never be supported
    char buf[128 + KRT_METRICS_MAX*8 + nh_bufsize(a->nexthops)];
         ^
1 error generated.

sysdep/linux/netlink.c

index 6cf404847162a5f0b003c854be4be8ba94b12cff..7b1f2dda78e15ae7a5afefa22bd721e2ab243bae 100644 (file)
@@ -6,6 +6,7 @@
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
+#include <alloca.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -915,44 +916,49 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
   eattr *ea;
   net *net = e->net;
   rta *a = e->attrs;
+  int bufsize = 128 + KRT_METRICS_MAX*8 + nh_bufsize(a->nexthops);
+
   struct {
     struct nlmsghdr h;
     struct rtmsg r;
-    char buf[128 + KRT_METRICS_MAX*8 + nh_bufsize(a->nexthops)];
-  } r;
+    char buf[0];
+  } *r;
+
+  int rsize = sizeof(*r) + bufsize;
+  r = alloca(rsize);
 
   DBG("nl_send_route(%N,new=%d)\n", net->n.addr, new);
 
-  bzero(&r.h, sizeof(r.h));
-  bzero(&r.r, sizeof(r.r));
-  r.h.nlmsg_type = new ? RTM_NEWROUTE : RTM_DELROUTE;
-  r.h.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-  r.h.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | (new ? NLM_F_CREATE|NLM_F_EXCL : 0);
+  bzero(&r->h, sizeof(r->h));
+  bzero(&r->r, sizeof(r->r));
+  r->h.nlmsg_type = new ? RTM_NEWROUTE : RTM_DELROUTE;
+  r->h.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+  r->h.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | (new ? NLM_F_CREATE|NLM_F_EXCL : 0);
 
-  r.r.rtm_family = p->af;
-  r.r.rtm_dst_len = net_pxlen(net->n.addr);
-  r.r.rtm_protocol = RTPROT_BIRD;
-  r.r.rtm_scope = RT_SCOPE_UNIVERSE;
-  nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net_prefix(net->n.addr));
+  r->r.rtm_family = p->af;
+  r->r.rtm_dst_len = net_pxlen(net->n.addr);
+  r->r.rtm_protocol = RTPROT_BIRD;
+  r->r.rtm_scope = RT_SCOPE_UNIVERSE;
+  nl_add_attr_ipa(&r->h, rsize, RTA_DST, net_prefix(net->n.addr));
 
   if (krt_table_id(p) < 256)
-    r.r.rtm_table = krt_table_id(p);
+    r->r.rtm_table = krt_table_id(p);
   else
-    nl_add_attr_u32(&r.h, sizeof(r), RTA_TABLE, krt_table_id(p));
+    nl_add_attr_u32(&r->h, rsize, RTA_TABLE, krt_table_id(p));
 
   /* For route delete, we do not specify route attributes */
   if (!new)
-    return nl_exchange(&r.h);
+    return nl_exchange(&r->h);
 
 
   if (ea = ea_find(eattrs, EA_KRT_METRIC))
-    nl_add_attr_u32(&r.h, sizeof(r), RTA_PRIORITY, ea->u.data);
+    nl_add_attr_u32(&r->h, rsize, RTA_PRIORITY, ea->u.data);
 
   if (ea = ea_find(eattrs, EA_KRT_PREFSRC))
-    nl_add_attr_ipa(&r.h, sizeof(r), RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data);
+    nl_add_attr_ipa(&r->h, rsize, RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data);
 
   if (ea = ea_find(eattrs, EA_KRT_REALM))
-    nl_add_attr_u32(&r.h, sizeof(r), RTA_FLOW, ea->u.data);
+    nl_add_attr_u32(&r->h, rsize, RTA_FLOW, ea->u.data);
 
 
   u32 metrics[KRT_METRICS_MAX];
@@ -967,7 +973,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
   }
 
   if (metrics[0])
-    nl_add_metrics(&r.h, sizeof(r), metrics, KRT_METRICS_MAX);
+    nl_add_metrics(&r->h, rsize, metrics, KRT_METRICS_MAX);
 
 
   /* a->iface != NULL checked in krt_capable() for router and device routes */
@@ -975,32 +981,32 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
   switch (a->dest)
     {
     case RTD_ROUTER:
-      r.r.rtm_type = RTN_UNICAST;
-      nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index);
-      nl_add_attr_ipa(&r.h, sizeof(r), RTA_GATEWAY, a->gw);
+      r->r.rtm_type = RTN_UNICAST;
+      nl_add_attr_u32(&r->h, rsize, RTA_OIF, a->iface->index);
+      nl_add_attr_ipa(&r->h, rsize, RTA_GATEWAY, a->gw);
       break;
     case RTD_DEVICE:
-      r.r.rtm_type = RTN_UNICAST;
-      nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index);
+      r->r.rtm_type = RTN_UNICAST;
+      nl_add_attr_u32(&r->h, rsize, RTA_OIF, a->iface->index);
       break;
     case RTD_BLACKHOLE:
-      r.r.rtm_type = RTN_BLACKHOLE;
+      r->r.rtm_type = RTN_BLACKHOLE;
       break;
     case RTD_UNREACHABLE:
-      r.r.rtm_type = RTN_UNREACHABLE;
+      r->r.rtm_type = RTN_UNREACHABLE;
       break;
     case RTD_PROHIBIT:
-      r.r.rtm_type = RTN_PROHIBIT;
+      r->r.rtm_type = RTN_PROHIBIT;
       break;
     case RTD_MULTIPATH:
-      r.r.rtm_type = RTN_UNICAST;
-      nl_add_multipath(&r.h, sizeof(r), a->nexthops);
+      r->r.rtm_type = RTN_UNICAST;
+      nl_add_multipath(&r->h, rsize, a->nexthops);
       break;
     default:
       bug("krt_capable inconsistent with nl_send_route");
     }
 
-  return nl_exchange(&r.h);
+  return nl_exchange(&r->h);
 }
 
 void