From: Maria Matejka Date: Tue, 27 May 2025 08:58:23 +0000 (+0200) Subject: Filters: Re-enabling onlink nexthop attribute X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1957b2ae0ee596965fed5d7a5a74e78e49acd5e;p=thirdparty%2Fbird.git Filters: Re-enabling onlink nexthop attribute There are still some semantic problems wrt. VRF settings, effectively allowing botched nexthops to slip through filters, but it makes more sense to re-enable onlink setting, than to wait until we find out how to do that all properly. This resolves #258. --- diff --git a/filter/config.Y b/filter/config.Y index 8da771ff3..d2719637b 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -367,7 +367,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, IF, THEN, ELSE, CASE, FOR, IN, DO, TRUE, FALSE, RT, RO, UNKNOWN, GENERIC, - FROM, GW, NET, PROTO, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, + FROM, GW, NET, PROTO, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK, ROA_CHECK, ASPA_CHECK, DEFINED, ADD, DELETE, RESET, @@ -904,6 +904,7 @@ static_attr: | IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); } | WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); } | GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); } + | ONLINK { $$ = f_new_static_attr(T_BOOL, SA_ONLINK, 0); } ; term_dot_method: term '.' { f_method_call_start($1); } method_name_cont { f_method_call_end(); $$ = $4; }; diff --git a/filter/data.h b/filter/data.h index baee14c8e..dcc0501e5 100644 --- a/filter/data.h +++ b/filter/data.h @@ -39,6 +39,7 @@ enum f_sa_code { SA_IFINDEX, SA_WEIGHT, SA_GW_MPLS, + SA_ONLINK, } PACKED; /* Static attribute definition (members of struct rta) */ diff --git a/filter/f-inst.c b/filter/f-inst.c index aeea55eaf..37017055a 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -725,6 +725,9 @@ case SA_GW_MPLS: RESULT(sa.type, i, (nh && nh->labels) ? nh->label[0] : MPLS_NULL); break; + case SA_ONLINK: + RESULT(sa.type, i, (nh && !!(nh->flags & RNF_ONLINK))); + break; default: bug("Invalid static attribute access (%u/%u)", sa.type, sa.sa_code); } @@ -773,10 +776,11 @@ struct nexthop *first = NEXTHOP_IS_REACHABLE(nhad) ? &(nhad->nh) : NULL; ip_addr ip = v1.val.ip; - struct iface *ifa = (ipa_is_link_local(ip) && first) ? first->iface : NULL; + bool onlink = first && (first->flags & RNF_ONLINK); + struct iface *ifa = ((ipa_is_link_local(ip) || onlink) && first) ? first->iface : NULL; /* XXX this code supposes that every owner is a protocol XXX */ - neighbor *n = neigh_find(SKIP_BACK(struct proto, sources, fs->rte->src->owner), ip, ifa, 0); + neighbor *n = neigh_find(SKIP_BACK(struct proto, sources, fs->rte->src->owner), ip, ifa, onlink ? NEF_ONLINK : 0); if (!n || (n->scope == SCOPE_HOST)) runtime( "Invalid gw address" ); @@ -846,6 +850,33 @@ } break; + case SA_ONLINK: + { + int i = v1.val.i; + + struct eattr *nh_ea = ea_find(fs->rte->attrs, &ea_gen_nexthop); + if (!nh_ea) + runtime( "Set iface first to make the nexthop onlink" ); + + struct nexthop_adata *nhad = (struct nexthop_adata *) nh_ea->u.ptr; + if (!NEXTHOP_IS_REACHABLE(nhad)) + runtime( "Set iface first to make the nexthop onlink" ); + + struct nexthop_adata *nhax = (struct nexthop_adata *) tmp_copy_adata(&nhad->ad); + + /* Set onlink on all next hops */ + if (i) + NEXTHOP_WALK(nh, nhax) + nh->flags |= RNF_ONLINK; + else + NEXTHOP_WALK(nh, nhax) + nh->flags &= ~RNF_ONLINK; + + a = ea_set_attr(&fs->rte->attrs, + EA_LITERAL_DIRECT_ADATA(&ea_gen_nexthop, 0, &nhax->ad)); + } + break; + default: bug("Invalid static attribute access (%u/%u)", sa.type, sa.sa_code); }