I've also made a quick patch for the kerenel protocol to accept routes of
type local. But it might be not well backward-compatible, because somebody
might receive some new routes in their kernel protocols. Anyway, with this
patch you can use something like that to have your IP route:
protocol kernel6 {
kernel table 255; # table local
learn all; # accept kernel routes as well
scan time 10;
ipv6 {
import all;
export none;
};
}
On Tue, Sep 30, 2025 at 8:39 PM Alexander Zubkov <[email protected]> wrote:
> Hi Anthony,
>
> You mean you have for example ip address with mask configured on eth0:
> 2001:db8::cafe/64. And you want to have route 2001:db8::cafe/128 inside
> bird without having to specify it manually in a static protocol for
> example? And now you have to make a dummy interface with 2001:db8::cafe/128
> configured on it?
> AFAIK, you cannot do that automatically in bird (i.e. change network mask
> of prefix). I thought if it would be possible to import single IP route
> from "table local", Linux has such routes for IPs configured for the system:
>
> local 2001:db8::cafe dev eth0 table local proto kernel metric 0 pref medium
>
> But bird ignores routes with type local, so it would need some patching of
> the source to do that.
> Also IMHO, having IPs with overlapping prefixes should work well on Linux
> if you know what you do.
> You can also use such config, when you configure for
> example 2001:db8::cafe/128 on eth0 and add device-route for 2001:db8::/64
> on dev eth0. But that might not work for automatic configurations - DHCP,
> SLAAC.
>
> Regards,
> Alexander Zubkov
>
>
> On Tue, Sep 30, 2025 at 7:24 PM Anthony Hoppe via Bird-users <
> [email protected]> wrote:
>
>> Hello List!
>>
>> I am working on a project to bring L3 down to the individual host and
>> am thinking through the transitionary configuration.
>>
>> For the purposes of this discussion, the hosts are assigned IPv4
>> addresses within a /24 and IPv6 addresses within a /64.
>>
>> Currently, I'm using a dummy interface and adding the IPs they own as
>> v4 /32 and v6 /128 and in combination with an export filter to only
>> export /32 and /128 prefixes, this works great.
>>
>> However, I was wondering if there is a way to configure BIRD so that
>> for the IPs configured on the host it supplants the configured prefix
>> with /32 and/or /128 allowing me to eliminate the dummy interface?
>>
>> The dummy interface is mostly a transitory step as Linux (Debian, at
>> least) will not let me assign a /32 or /128 to an interface where a
>> larger overlapping prefix resides (which yes, I understand why you
>> normally don't want to do this, haha).
>>
>> ~ Anthony
>>
>> --
>> This email, including its contents and any attachment(s), may contain
>> confidential and/or proprietary information and is solely for the review
>> and use of the intended recipient(s). If you have received this email in
>> error, please notify the sender and permanently delete this email, its
>> content, and any attachment(s). Any disclosure, copying, or taking of
>> any
>> action in reliance on an email received in error is strictly prohibited.
>>
>
diff --git a/nest/config.Y b/nest/config.Y
index 4a3b45b50..acc1a09cf 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -137,7 +137,7 @@ CF_ENUM(T_ENUM_RTS, RTS_, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL, RPKI, L3VPN,
AGGREGATED)
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
-CF_ENUM(T_ENUM_RTD, RTD_, UNICAST, BLACKHOLE, UNREACHABLE, PROHIBIT)
+CF_ENUM(T_ENUM_RTD, RTD_, UNICAST, BLACKHOLE, UNREACHABLE, PROHIBIT, LOCAL)
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
CF_ENUM(T_ENUM_ASPA, ASPA_, UNKNOWN, VALID, INVALID)
CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6)
diff --git a/nest/route.h b/nest/route.h
index 5a9e7fa16..24fb73193 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -491,7 +491,8 @@ typedef struct rta {
#define RTD_BLACKHOLE 2 /* Silently drop packets */
#define RTD_UNREACHABLE 3 /* Reject as unreachable */
#define RTD_PROHIBIT 4 /* Administratively prohibited */
-#define RTD_MAX 5
+#define RTD_LOCAL 5 /* Accept locally */
+#define RTD_MAX 6
#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
protocol-specific metric is availabe */
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index e10e1ecbf..33b3aff83 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -86,6 +86,7 @@ const char * rta_dest_names[RTD_MAX] = {
[RTD_BLACKHOLE] = "blackhole",
[RTD_UNREACHABLE] = "unreachable",
[RTD_PROHIBIT] = "prohibited",
+ [RTD_LOCAL] = "local",
};
pool *rta_pool;
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 299f132fe..a01c45c57 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -1770,6 +1770,9 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
case RTN_PROHIBIT:
ra->dest = RTD_PROHIBIT;
break;
+ case RTN_LOCAL:
+ ra->dest = RTD_LOCAL;
+ break;
/* FIXME: What about RTN_THROW? */
default:
SKIP("type %d\n", i->rtm_type);