]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filters: Re-enabling onlink nexthop attribute
authorMaria Matejka <mq@ucw.cz>
Tue, 27 May 2025 08:58:23 +0000 (10:58 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 27 May 2025 09:51:31 +0000 (11:51 +0200)
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.

filter/config.Y
filter/data.h
filter/f-inst.c

index 8da771ff356b6664feaae99a9e57be9e097a79f4..d2719637be45e5a056e157d8850ad696fad1877a 100644 (file)
@@ -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; };
index baee14c8e20e9e24df085f0bec114419433377b0..dcc0501e5399e35fae0940f0d4dbd46131cd79e8 100644 (file)
@@ -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) */
index aeea55eafdc7835a3c3b4fcea028712de72c5139..37017055a2e0ac25791e3b9ff84392597b42b8aa 100644 (file)
            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);
       }