Portability: Fixed C extension error generated by CLang.

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.
This commit is contained in:
Jan Moskyto Matejka 2016-04-27 14:45:14 +02:00
parent 7152e5efbb
commit a8caff322f

View file

@ -6,6 +6,7 @@
* Can be freely distributed and used under the terms of the GNU GPL. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
#include <alloca.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.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; eattr *ea;
net *net = e->net; net *net = e->net;
rta *a = e->attrs; rta *a = e->attrs;
int bufsize = 128 + KRT_METRICS_MAX*8 + nh_bufsize(a->nexthops);
struct { struct {
struct nlmsghdr h; struct nlmsghdr h;
struct rtmsg r; struct rtmsg r;
char buf[128 + KRT_METRICS_MAX*8 + nh_bufsize(a->nexthops)]; char buf[0];
} r; } *r;
int rsize = sizeof(*r) + bufsize;
r = alloca(rsize);
DBG("nl_send_route(%N,new=%d)\n", net->n.addr, new); DBG("nl_send_route(%N,new=%d)\n", net->n.addr, new);
bzero(&r.h, sizeof(r.h)); bzero(&r->h, sizeof(r->h));
bzero(&r.r, sizeof(r.r)); bzero(&r->r, sizeof(r->r));
r.h.nlmsg_type = new ? RTM_NEWROUTE : RTM_DELROUTE; r->h.nlmsg_type = new ? RTM_NEWROUTE : RTM_DELROUTE;
r.h.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); 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->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_family = p->af;
r.r.rtm_dst_len = net_pxlen(net->n.addr); r->r.rtm_dst_len = net_pxlen(net->n.addr);
r.r.rtm_protocol = RTPROT_BIRD; r->r.rtm_protocol = RTPROT_BIRD;
r.r.rtm_scope = RT_SCOPE_UNIVERSE; r->r.rtm_scope = RT_SCOPE_UNIVERSE;
nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net_prefix(net->n.addr)); nl_add_attr_ipa(&r->h, rsize, RTA_DST, net_prefix(net->n.addr));
if (krt_table_id(p) < 256) if (krt_table_id(p) < 256)
r.r.rtm_table = krt_table_id(p); r->r.rtm_table = krt_table_id(p);
else 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 */ /* For route delete, we do not specify route attributes */
if (!new) if (!new)
return nl_exchange(&r.h); return nl_exchange(&r->h);
if (ea = ea_find(eattrs, EA_KRT_METRIC)) 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)) 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)) 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]; 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]) 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 */ /* 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) switch (a->dest)
{ {
case RTD_ROUTER: case RTD_ROUTER:
r.r.rtm_type = RTN_UNICAST; r->r.rtm_type = RTN_UNICAST;
nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index); nl_add_attr_u32(&r->h, rsize, RTA_OIF, a->iface->index);
nl_add_attr_ipa(&r.h, sizeof(r), RTA_GATEWAY, a->gw); nl_add_attr_ipa(&r->h, rsize, RTA_GATEWAY, a->gw);
break; break;
case RTD_DEVICE: case RTD_DEVICE:
r.r.rtm_type = RTN_UNICAST; r->r.rtm_type = RTN_UNICAST;
nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index); nl_add_attr_u32(&r->h, rsize, RTA_OIF, a->iface->index);
break; break;
case RTD_BLACKHOLE: case RTD_BLACKHOLE:
r.r.rtm_type = RTN_BLACKHOLE; r->r.rtm_type = RTN_BLACKHOLE;
break; break;
case RTD_UNREACHABLE: case RTD_UNREACHABLE:
r.r.rtm_type = RTN_UNREACHABLE; r->r.rtm_type = RTN_UNREACHABLE;
break; break;
case RTD_PROHIBIT: case RTD_PROHIBIT:
r.r.rtm_type = RTN_PROHIBIT; r->r.rtm_type = RTN_PROHIBIT;
break; break;
case RTD_MULTIPATH: case RTD_MULTIPATH:
r.r.rtm_type = RTN_UNICAST; r->r.rtm_type = RTN_UNICAST;
nl_add_multipath(&r.h, sizeof(r), a->nexthops); nl_add_multipath(&r->h, rsize, a->nexthops);
break; break;
default: default:
bug("krt_capable inconsistent with nl_send_route"); bug("krt_capable inconsistent with nl_send_route");
} }
return nl_exchange(&r.h); return nl_exchange(&r->h);
} }
void void