Skip to content

Commit 355ccce

Browse files
committed
route: allow IPv6 gateway in IPv4 route
Linux supports it by using RTA_VIA instead of RTA_GATEWAY. Since it essentially acts as gateway, we extend the current API to allow it.
1 parent 515471f commit 355ccce

File tree

2 files changed

+16
-24
lines changed

2 files changed

+16
-24
lines changed

examples/add_route.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async fn add_route(
4242
) -> Result<(), Error> {
4343
let route = RouteMessageBuilder::<Ipv4Addr>::new()
4444
.destination_prefix(dest.ip(), dest.prefix())
45-
.gateway(gateway.ip())
45+
.gateway(gateway.ip().into())
4646
.table_id(TEST_TABLE_ID)
4747
.build();
4848
handle.route().add(route).execute().await?;

src/route/builder.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
use netlink_packet_route::{
99
route::{
1010
RouteAddress, RouteAttribute, RouteHeader, RouteMessage, RouteProtocol,
11-
RouteScope, RouteType,
11+
RouteScope, RouteType, RouteVia,
1212
},
1313
AddressFamily,
1414
};
@@ -153,10 +153,12 @@ impl RouteMessageBuilder<Ipv4Addr> {
153153
}
154154

155155
/// Sets the gateway (via) address.
156-
pub fn gateway(mut self, addr: Ipv4Addr) -> Self {
157-
self.message
158-
.attributes
159-
.push(RouteAttribute::Gateway(RouteAddress::Inet(addr)));
156+
pub fn gateway(mut self, addr: IpAddr) -> Self {
157+
let attr = match addr {
158+
IpAddr::V4(v4) => RouteAttribute::Gateway(RouteAddress::Inet(v4)),
159+
IpAddr::V6(v6) => RouteAttribute::Via(RouteVia::Inet6(v6)),
160+
};
161+
self.message.attributes.push(attr);
160162
self
161163
}
162164
}
@@ -351,25 +353,15 @@ impl RouteMessageBuilder<IpAddr> {
351353
mut self,
352354
addr: IpAddr,
353355
) -> Result<Self, InvalidRouteMessage> {
354-
self.set_address_family_from_ip_addr(addr);
355-
match self.message.header.address_family {
356-
AddressFamily::Inet => {
357-
if addr.is_ipv6() {
358-
return Err(InvalidRouteMessage::Gateway(addr));
359-
};
356+
use AddressFamily::*;
357+
let attr = match (self.message.header.address_family, addr) {
358+
(Inet, addr @ IpAddr::V4(_)) | (Inet6, addr @ IpAddr::V6(_)) => {
359+
RouteAttribute::Gateway(addr.into())
360360
}
361-
AddressFamily::Inet6 => {
362-
if addr.is_ipv4() {
363-
return Err(InvalidRouteMessage::Gateway(addr));
364-
};
365-
}
366-
af => {
367-
return Err(InvalidRouteMessage::AddressFamily(af));
368-
}
369-
}
370-
self.message
371-
.attributes
372-
.push(RouteAttribute::Gateway(addr.into()));
361+
(Inet, IpAddr::V6(v6)) => RouteAttribute::Via(RouteVia::Inet6(v6)),
362+
(af, _) => return Err(InvalidRouteMessage::AddressFamily(af)),
363+
};
364+
self.message.attributes.push(attr);
373365
Ok(self)
374366
}
375367

0 commit comments

Comments
 (0)