From 1d309c4ce6e95b68c64a8f007f6dd2f1830a5707 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Thu, 14 Apr 2022 16:51:18 +0200 Subject: Enforcing certain data structure explicit paddings. Implicit paddings have undefined values in C. We want the eattr blocks to be comparable by memcmp and eattrs settable directly by structrure literals. This check ensures that all paddings in eattr and bval are explicit and therefore zeroed in all literals. --- lib/type_test.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 lib/type_test.c (limited to 'lib/type_test.c') diff --git a/lib/type_test.c b/lib/type_test.c new file mode 100644 index 00000000..20e7630b --- /dev/null +++ b/lib/type_test.c @@ -0,0 +1,78 @@ +/* + * BIRD Library -- Data Type Alignment Tests + * + * (c) 2022 Maria Matejka + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include "test/birdtest.h" +#include "lib/type.h" +#include "lib/route.h" + +#define CHECK_ONE(val) \ + for (uint i=0; i Date: Wed, 4 May 2022 14:41:51 +0200 Subject: Moved route source attribute (RTS_*) to eattrs --- filter/config.Y | 3 +-- filter/data.h | 1 - filter/f-inst.c | 1 - lib/route.h | 12 +++++++++--- lib/type_test.c | 1 + nest/rt-attr.c | 32 ++++++++++++++++++++------------ nest/rt-dev.c | 2 +- nest/rt-table.c | 8 ++++---- proto/babel/babel.c | 6 +++--- proto/bgp/attrs.c | 2 +- proto/bgp/config.Y | 2 +- proto/bgp/packets.c | 2 +- proto/ospf/ospf.c | 22 +++++++++++++--------- proto/ospf/rt.c | 21 ++++++++++++++++----- proto/perf/perf.c | 2 +- proto/rip/rip.c | 4 ++-- proto/rpki/rpki.c | 2 +- proto/static/static.c | 2 +- sysdep/bsd/krt-sock.c | 3 ++- sysdep/linux/netlink.c | 2 +- 20 files changed, 79 insertions(+), 51 deletions(-) (limited to 'lib/type_test.c') diff --git a/filter/config.Y b/filter/config.Y index 6af39c10..ca792593 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -285,7 +285,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST, IF, THEN, ELSE, CASE, TRUE, FALSE, RT, RO, UNKNOWN, GENERIC, - FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, + FROM, GW, NET, MASK, PROTO, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ROA_CHECK, ASN, SRC, DST, IS_V4, IS_V6, LEN, MAXLEN, @@ -765,7 +765,6 @@ static_attr: GW { $$ = f_new_static_attr(T_IP, SA_GW, 0); } | NET { $$ = f_new_static_attr(T_NET, SA_NET, 1); } | PROTO { $$ = f_new_static_attr(T_STRING, SA_PROTO, 1); } - | SOURCE { $$ = f_new_static_attr(T_ENUM_RTS, SA_SOURCE, 1); } | DEST { $$ = f_new_static_attr(T_ENUM_RTD, SA_DEST, 0); } | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); } | IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); } diff --git a/filter/data.h b/filter/data.h index 49b29499..23db4a85 100644 --- a/filter/data.h +++ b/filter/data.h @@ -25,7 +25,6 @@ enum f_sa_code { SA_GW = 1, SA_NET, SA_PROTO, - SA_SOURCE, SA_DEST, SA_IFNAME, SA_IFINDEX, diff --git a/filter/f-inst.c b/filter/f-inst.c index 5eacc716..23271ce7 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -536,7 +536,6 @@ case SA_GW: RESULT(sa.type, ip, rta->nh.gw); break; case SA_NET: RESULT(sa.type, net, (*fs->rte)->net->n.addr); break; case SA_PROTO: RESULT(sa.type, s, (*fs->rte)->src->proto->name); break; - case SA_SOURCE: RESULT(sa.type, i, rta->source); break; case SA_DEST: RESULT(sa.type, i, rta->dest); break; case SA_IFNAME: RESULT(sa.type, s, rta->nh.iface ? rta->nh.iface->name : ""); break; case SA_IFINDEX: RESULT(sa.type, i, rta->nh.iface ? rta->nh.iface->index : 0); break; diff --git a/lib/route.h b/lib/route.h index 40ba150d..8fdb5d8b 100644 --- a/lib/route.h +++ b/lib/route.h @@ -85,7 +85,6 @@ typedef struct rta { struct ea_list *eattrs; /* Extended Attribute chain */ struct hostentry *hostentry; /* Hostentry for recursive next-hops */ u16 cached:1; /* Are attributes cached? */ - u16 source:7; /* Route source (RTS_...) */ u16 dest:4; /* Route destination type (RTD_...) */ struct nexthop nh; /* Next hop */ } rta; @@ -131,12 +130,13 @@ static inline int rte_is_reachable(rte *r) typedef struct eattr { word id; /* EA_CODE(PROTOCOL_..., protocol-dependent ID) */ byte flags; /* Protocol-dependent flags */ - byte type:5; /* Attribute type */ + byte type; /* Attribute type */ + byte rfu:5; byte originated:1; /* The attribute has originated locally */ byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */ byte undef:1; /* Explicitly undefined */ - PADDING(unused, 0, 4); + PADDING(unused, 3, 3); union bval u; } eattr; @@ -308,6 +308,12 @@ u32 rt_get_igp_metric(rte *rt); /* From: Advertising router */ extern struct ea_class ea_gen_from; +/* Source: An old method to devise the route source protocol and kind. + * To be superseded in a near future by something more informative. */ +extern struct ea_class ea_gen_source; +static inline u32 rt_get_source_attr(rte *rt) +{ return ea_get_int(rt->attrs->eattrs, &ea_gen_source, 0); } + /* Next hop structures */ #define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK) diff --git a/lib/type_test.c b/lib/type_test.c index 20e7630b..b526db69 100644 --- a/lib/type_test.c +++ b/lib/type_test.c @@ -54,6 +54,7 @@ t_eattr(void) e.id = ~0; e.flags = ~0; e.type = ~0; + e.rfu = ~0; e.originated = ~0; e.fresh = ~0; e.undef = ~0; diff --git a/nest/rt-attr.c b/nest/rt-attr.c index a892bfd5..39fd7db4 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -92,6 +92,22 @@ const char * const rta_src_names[RTS_MAX] = { [RTS_RPKI] = "RPKI", }; +static void +ea_gen_source_format(const eattr *a, byte *buf, uint size) +{ + if ((a->u.data >= RTS_MAX) || !rta_src_names[a->u.data]) + bsnprintf(buf, size, "unknown"); + else + bsnprintf(buf, size, "%s", rta_src_names[a->u.data]); +} + +struct ea_class ea_gen_source = { + .name = "source", + .type = T_ENUM_RTS, + .readonly = 1, + .format = ea_gen_source_format, +}; + const char * rta_dest_names[RTD_MAX] = { [RTD_NONE] = "", [RTD_UNICAST] = "unicast", @@ -1234,7 +1250,6 @@ rta_hash(rta *a) #define MIX(f) mem_hash_mix(&h, &(a->f), sizeof(a->f)); #define BMIX(f) mem_hash_mix_num(&h, a->f); MIX(hostentry); - BMIX(source); BMIX(dest); #undef MIX @@ -1244,8 +1259,7 @@ rta_hash(rta *a) static inline int rta_same(rta *x, rta *y) { - return (x->source == y->source && - x->dest == y->dest && + return (x->dest == y->dest && x->hostentry == y->hostentry && nexthop_same(&(x->nh), &(y->nh)) && ea_same(x->eattrs, y->eattrs)); @@ -1388,15 +1402,10 @@ rta_do_cow(rta *o, linpool *lp) void rta_dump(rta *a) { - static char *rts[] = { "", "RTS_STATIC", "RTS_INHERIT", "RTS_DEVICE", - "RTS_STAT_DEV", "RTS_REDIR", "RTS_RIP", - "RTS_OSPF", "RTS_OSPF_IA", "RTS_OSPF_EXT1", - "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" }; static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" }; - debug("uc=%d %s %s h=%04x", - a->uc, rts[a->source], - rtd[a->dest], a->hash_key); + debug("uc=%d %s h=%04x", + a->uc, rtd[a->dest], a->hash_key); if (!a->cached) debug(" !CACHED"); if (a->dest == RTD_UNICAST) @@ -1441,8 +1450,6 @@ rta_dump_all(void) void rta_show(struct cli *c, rta *a) { - cli_printf(c, -1008, "\tType: %s", rta_src_names[a->source]); - for(ea_list *eal = a->eattrs; eal; eal=eal->next) for(int i=0; icount; i++) ea_show(c, &eal->attrs[i]); @@ -1476,6 +1483,7 @@ rta_init(void) ea_register_init(&ea_gen_preference); ea_register_init(&ea_gen_igp_metric); ea_register_init(&ea_gen_from); + ea_register_init(&ea_gen_source); } /* diff --git a/nest/rt-dev.c b/nest/rt-dev.c index ffd5afd5..af6506f6 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -83,12 +83,12 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) struct rte_src *src = rt_get_source(P, ad->iface->index); rta a0 = { - .source = RTS_DEVICE, .dest = RTD_UNICAST, .nh.iface = ad->iface, }; ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, c->preference); + ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_DEVICE); a = rta_lookup(&a0); e = rte_get_temp(a, src); diff --git a/nest/rt-table.c b/nest/rt-table.c index e8b04e0b..4f119ac0 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -2588,7 +2588,7 @@ rt_flowspec_check(rtable *tab_ip, rtable *tab_flow, const net_addr *n, rta *a, i trie_add_prefix(tab_flow->flowspec_trie, &dst, (nb ? nb->n.addr->pxlen : 0), max_pxlen); /* No best-match BGP route -> no flowspec */ - if (!rb || (rb->attrs->source != RTS_BGP)) + if (!rb || (rt_get_source_attr(rb) != RTS_BGP)) return 0; /* Find ORIGINATOR_ID values */ @@ -2620,7 +2620,7 @@ rt_flowspec_check(rtable *tab_ip, rtable *tab_flow, const net_addr *n, rta *a, i continue; rte *rc = nc->routes; - if (rc->attrs->source != RTS_BGP) + if (rt_get_source_attr(rc) != RTS_BGP) return 0; if (rta_get_first_asn(rc->attrs) != asn_b) @@ -2637,7 +2637,7 @@ static rte * rt_flowspec_update_rte(rtable *tab, rte *r) { #ifdef CONFIG_BGP - if (r->attrs->source != RTS_BGP) + if (rt_get_source_attr(r) != RTS_BGP) return NULL; struct bgp_channel *bc = (struct bgp_channel *) r->sender; @@ -3471,7 +3471,7 @@ rt_get_igp_metric(rte *rt) if (ea) return ea->u.data; - if (rt->attrs->source == RTS_DEVICE) + if (rt_get_source_attr(rt) == RTS_DEVICE) return 0; if (rt->src->proto->rte_igp_metric) diff --git a/proto/babel/babel.c b/proto/babel/babel.c index cd221c7b..a7dcee09 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -645,12 +645,13 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) { struct { ea_list l; - eattr a[5]; + eattr a[6]; } eattrs = { .l.count = ARRAY_SIZE(eattrs.a), .a = { EA_LITERAL_EMBEDDED(&ea_gen_preference, 0, c->preference), EA_LITERAL_STORE_ADATA(&ea_gen_from, 0, &r->neigh->addr, sizeof(r->neigh->addr)), + EA_LITERAL_EMBEDDED(&ea_gen_source, 0, RTS_BABEL), EA_LITERAL_EMBEDDED(&ea_babel_metric, 0, r->metric), EA_LITERAL_STORE_ADATA(&ea_babel_router_id, 0, &r->router_id, sizeof(r->router_id)), EA_LITERAL_EMBEDDED(&ea_babel_seqno, 0, r->seqno), @@ -658,7 +659,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) }; rta a0 = { - .source = RTS_BABEL, .dest = RTD_UNICAST, .nh.gw = r->next_hop, .nh.iface = r->neigh->ifa->iface, @@ -683,11 +683,11 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) { /* Unreachable */ rta a0 = { - .source = RTS_BABEL, .dest = RTD_UNREACHABLE, }; ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, 1); + ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_BABEL); rta *a = rta_lookup(&a0); rte *rte = rte_get_temp(a, p->p.main_source); diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 097ba9a2..1efc26ce 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -402,7 +402,7 @@ bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad) static inline int bgp_init_aigp_metric(rte *e, u64 *metric, const struct adata **ad) { - if (e->attrs->source == RTS_BGP) + if (rt_get_source_attr(e) == RTS_BGP) return 0; *metric = rt_get_igp_metric(e); diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index b4d8b83f..24f3ec8f 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -43,7 +43,7 @@ CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER, CF_GRAMMAR -toksym: BGP_MED | BGP_LOCAL_PREF ; +toksym: BGP_MED | BGP_LOCAL_PREF | SOURCE ; proto: bgp_proto '}' ; diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 62d60e9a..0aa4dc40 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -2474,11 +2474,11 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis { a = allocz(RTA_MAX_SIZE); - a->source = RTS_BGP; a->eattrs = ea; ea_set_attr_data(&a->eattrs, &ea_gen_from, 0, &s->proto->remote_ip, sizeof(ip_addr)); ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, c->c.preference); + ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_BGP); c->desc->decode_next_hop(s, nh, nh_len, a); bgp_finish_attrs(s, a); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 427c2c86..731adaa5 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -392,15 +392,18 @@ ospf_rte_better(struct rte *new, struct rte *old) if (new_metric1 == LSINFINITY) return 0; - if(new->attrs->source < old->attrs->source) return 1; - if(new->attrs->source > old->attrs->source) return 0; + u32 ns = rt_get_source_attr(new); + u32 os = rt_get_source_attr(old); - if(new->attrs->source == RTS_OSPF_EXT2) + if (ns < os) return 1; + if (ns > os) return 0; + + if (ns == RTS_OSPF_EXT2) { u32 old_metric2 = ea_get_int(old->attrs->eattrs, &ea_ospf_metric2, LSINFINITY); u32 new_metric2 = ea_get_int(new->attrs->eattrs, &ea_ospf_metric2, LSINFINITY); - if(new_metric2 < old_metric2) return 1; - if(new_metric2 > old_metric2) return 0; + if (new_metric2 < old_metric2) return 1; + if (new_metric2 > old_metric2) return 0; } u32 old_metric1 = ea_get_int(old->attrs->eattrs, &ea_ospf_metric1, LSINFINITY); @@ -413,7 +416,7 @@ ospf_rte_better(struct rte *new, struct rte *old) static u32 ospf_rte_igp_metric(struct rte *rt) { - if (rt->attrs->source == RTS_OSPF_EXT2) + if (rt_get_source_attr(rt) == RTS_OSPF_EXT2) return IGP_METRIC_UNKNOWN; return ea_get_int(rt->attrs->eattrs, &ea_ospf_metric1, LSINFINITY); @@ -571,7 +574,8 @@ ospf_get_route_info(rte * rte, byte * buf) { char *type = ""; - switch (rte->attrs->source) + uint source = rt_get_source_attr(rte); + switch (source) { case RTS_OSPF: type = "I"; @@ -589,10 +593,10 @@ ospf_get_route_info(rte * rte, byte * buf) buf += bsprintf(buf, " %s", type); buf += bsprintf(buf, " (%d/%d", rt_get_preference(rte), ea_get_int(rte->attrs->eattrs, &ea_ospf_metric1, LSINFINITY)); - if (rte->attrs->source == RTS_OSPF_EXT2) + if (source == RTS_OSPF_EXT2) buf += bsprintf(buf, "/%d", ea_get_int(rte->attrs->eattrs, &ea_ospf_metric2, LSINFINITY)); buf += bsprintf(buf, ")"); - if (rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2) + if (source == RTS_OSPF_EXT1 || source == RTS_OSPF_EXT2) { eattr *ea = ea_find(rte->attrs->eattrs, &ea_ospf_tag); if (ea && (ea->u.data > 0)) diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index ddc5b162..91739056 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -2004,11 +2004,19 @@ static inline int ort_changed(ort *nf, rta *nr) { rta *or = nf->old_rta; - return !or || + + if (!or || (nf->n.metric1 != nf->old_metric1) || (nf->n.metric2 != nf->old_metric2) || (nf->n.tag != nf->old_tag) || (nf->n.rid != nf->old_rid) || - (nr->source != or->source) || (nr->dest != or->dest) || - !nexthop_same(&(nr->nh), &(or->nh)); + (nr->dest != or->dest) || + !nexthop_same(&(nr->nh), &(or->nh))) + return 1; + + if ( ea_get_int(nr->eattrs, &ea_gen_source, 0) + != ea_get_int(or->eattrs, &ea_gen_source, 0)) + return 1; + + return 0; } static void @@ -2053,7 +2061,6 @@ again1: if (nf->n.type) /* Add the route */ { rta a0 = { - .source = nf->n.type, .dest = RTD_UNICAST, .nh = *(nf->n.nhs), }; @@ -2067,7 +2074,7 @@ again1: struct { ea_list l; - eattr a[5]; + eattr a[6]; } eattrs; eattrs.l = (ea_list) {}; @@ -2075,6 +2082,9 @@ again1: eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_gen_preference, 0, p->p.main_channel->preference); + eattrs.a[eattrs.l.count++] = + EA_LITERAL_EMBEDDED(&ea_gen_source, 0, nf->n.type); + eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_ospf_metric1, 0, nf->n.metric1); @@ -2089,6 +2099,7 @@ again1: eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_ospf_router_id, 0, nf->n.rid); + ASSERT_DIE(ARRAY_SIZE(eattrs.a) >= eattrs.l.count); a0.eattrs = &eattrs.l; rta *a = rta_lookup(&a0); diff --git a/proto/perf/perf.c b/proto/perf/perf.c index 47a2867d..4329556c 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -143,7 +143,6 @@ perf_loop(void *data) if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) { struct rta a0 = { - .source = RTS_PERF, .dest = RTD_UNICAST, .nh.iface = p->ifa->iface, .nh.gw = gw, @@ -151,6 +150,7 @@ perf_loop(void *data) }; ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); + ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_PERF); p->data[i].a = rta_lookup(&a0); } diff --git a/proto/rip/rip.c b/proto/rip/rip.c index f5442606..f7f34c27 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -152,17 +152,17 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) { /* Update */ rta a0 = { - .source = RTS_RIP, .dest = RTD_UNICAST, }; struct { ea_list l; - eattr a[2]; + eattr a[3]; } ea_block = { .l.count = ARRAY_SIZE(ea_block.a), .a = { EA_LITERAL_EMBEDDED(&ea_gen_preference, 0, p->p.main_channel->preference), + EA_LITERAL_EMBEDDED(&ea_gen_source, 0, RTS_RIP), EA_LITERAL_EMBEDDED(&ea_rip_metric, 0, rt->metric), }, }; diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index af963f49..56d8add2 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -121,11 +121,11 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_ struct rpki_proto *p = cache->p; rta a0 = { - .source = RTS_RPKI, .dest = RTD_NONE, }; ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, channel->preference); + ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_RPKI); rta *a = rta_lookup(&a0); rte *e = rte_get_temp(a, p->p.main_source); diff --git a/proto/static/static.c b/proto/static/static.c index ff833b16..1400e985 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -55,9 +55,9 @@ static_announce_rte(struct static_proto *p, struct static_route *r) { rta *a = allocz(RTA_MAX_SIZE); struct rte_src *src = static_get_source(p, r->index); - a->source = RTS_STATIC; a->dest = r->dest; ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); + ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_STATIC); if (r->dest == RTD_UNICAST) { diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index bc6b1839..61ac7a5c 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -520,9 +520,10 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) rta a = { .src = p->p.main_source, - .source = RTS_INHERIT, }; + ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_INHERIT); + /* reject/blackhole routes have also set RTF_GATEWAY, we wil check them first. */ diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index c506c71c..e0219ce0 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -1854,7 +1854,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) nl_announce_route(s); rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE); - ra->source = RTS_INHERIT; + ea_set_attr_u32(&ra->eattrs, &ea_gen_source, 0, RTS_INHERIT); if (a[RTA_FLOW]) s->rta_flow = rta_get_u32(a[RTA_FLOW]); -- cgit v1.2.3