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,
| 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; };
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);
}
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" );
}
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);
}