Commit 191d295b authored by Théophile Bastian's avatar Théophile Bastian

Detect kernel support for v4-over-v6.

Detection is based on the kernel version, and can be overridden by
the configuration option `v4-over-v6 {true|false}`. If v4-over-v6 is not
supported, ignores v4-over-v6 routes early.
parent 95376364
...@@ -64,6 +64,7 @@ int debug = 0; ...@@ -64,6 +64,7 @@ int debug = 0;
int link_detect = 0; int link_detect = 0;
int all_wireless = 0; int all_wireless = 0;
int has_ipv6_subtrees = 0; int has_ipv6_subtrees = 0;
int has_v4ov6 = 0;
int default_wireless_hello_interval = -1; int default_wireless_hello_interval = -1;
int default_wired_hello_interval = -1; int default_wired_hello_interval = -1;
int resend_delay = -1; int resend_delay = -1;
...@@ -169,6 +170,7 @@ main(int argc, char **argv) ...@@ -169,6 +170,7 @@ main(int argc, char **argv)
protocol_port = 6696; protocol_port = 6696;
change_smoothing_half_life(4); change_smoothing_half_life(4);
has_ipv6_subtrees = kernel_has_ipv6_subtrees(); has_ipv6_subtrees = kernel_has_ipv6_subtrees();
has_v4ov6 = kernel_has_v4ov6();
while(1) { while(1) {
opt = getopt(argc, argv, opt = getopt(argc, argv,
......
...@@ -92,6 +92,7 @@ extern const char *logfile, *pidfile, *state_file; ...@@ -92,6 +92,7 @@ extern const char *logfile, *pidfile, *state_file;
extern int link_detect; extern int link_detect;
extern int all_wireless; extern int all_wireless;
extern int has_ipv6_subtrees; extern int has_ipv6_subtrees;
extern int has_v4ov6;
extern unsigned char myid[8]; extern unsigned char myid[8];
extern int have_id; extern int have_id;
......
...@@ -200,6 +200,11 @@ This specifies whether to use native source-specific IPv6 forwarding ...@@ -200,6 +200,11 @@ This specifies whether to use native source-specific IPv6 forwarding
rather than multiple routing tables. The default is chosen automatically rather than multiple routing tables. The default is chosen automatically
depending on the kernel version. depending on the kernel version.
.TP .TP
.BR v4-over-v6 " {" true | false }
This specifies whether to use v4-over-v6 routes (IPv4 routes with an IPv6
next-hop). This should not be enabled unless your kernel supports it. The
default is chosen automatically depending on the kernel version.
.TP
.BI debug " level" .BI debug " level"
This specifies the debugging level, and is equivalent to the command-line This specifies the debugging level, and is equivalent to the command-line
option option
......
...@@ -850,6 +850,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -850,6 +850,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
strcmp(token, "daemonise") == 0 || strcmp(token, "daemonise") == 0 ||
strcmp(token, "skip-kernel-setup") == 0 || strcmp(token, "skip-kernel-setup") == 0 ||
strcmp(token, "ipv6-subtrees") == 0 || strcmp(token, "ipv6-subtrees") == 0 ||
strcmp(token, "v4-over-v6") == 0 ||
strcmp(token, "reflect-kernel-metric") == 0) { strcmp(token, "reflect-kernel-metric") == 0) {
int b; int b;
c = getbool(c, &b, gnc, closure); c = getbool(c, &b, gnc, closure);
...@@ -866,6 +867,8 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -866,6 +867,8 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
skip_kernel_setup = b; skip_kernel_setup = b;
else if(strcmp(token, "ipv6-subtrees") == 0) else if(strcmp(token, "ipv6-subtrees") == 0)
has_ipv6_subtrees = b; has_ipv6_subtrees = b;
else if(strcmp(token, "v4-over-v6") == 0)
has_v4ov6 = b;
else if(strcmp(token, "reflect-kernel-metric") == 0) else if(strcmp(token, "reflect-kernel-metric") == 0)
reflect_kernel_metric = b; reflect_kernel_metric = b;
else else
......
...@@ -105,6 +105,7 @@ int gettime(struct timeval *tv); ...@@ -105,6 +105,7 @@ int gettime(struct timeval *tv);
int read_random_bytes(void *buf, int len); int read_random_bytes(void *buf, int len);
int kernel_older_than(const char *sysname, int version, int sub_version); int kernel_older_than(const char *sysname, int version, int sub_version);
int kernel_has_ipv6_subtrees(void); int kernel_has_ipv6_subtrees(void);
int kernel_has_v4ov6(void);
int add_rule(int prio, const unsigned char *src_prefix, int src_plen, int add_rule(int prio, const unsigned char *src_prefix, int src_plen,
int table); int table);
int flush_rule(int prio, int family); int flush_rule(int prio, int family);
......
...@@ -940,6 +940,14 @@ kernel_has_ipv6_subtrees(void) ...@@ -940,6 +940,14 @@ kernel_has_ipv6_subtrees(void)
return (kernel_older_than("Linux", 3, 11) == 0); return (kernel_older_than("Linux", 3, 11) == 0);
} }
int
kernel_has_v4ov6(void)
{
/* v4-over-v6 was introduced in Linux by commit
d15662682db232da77136cd348f4c9df312ca6f9 first released as 5.2 */
return (kernel_older_than("Linux", 5, 2) == 0);
}
int int
kernel_route(int operation, int table, kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen, const unsigned char *dest, unsigned short plen,
......
...@@ -401,6 +401,12 @@ kernel_has_ipv6_subtrees(void) ...@@ -401,6 +401,12 @@ kernel_has_ipv6_subtrees(void)
return 0; return 0;
} }
int
kernel_has_v4ov6(void)
{
return 0;
}
int int
kernel_route(int operation, int table, kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen, const unsigned char *dest, unsigned short plen,
......
...@@ -686,6 +686,13 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -686,6 +686,13 @@ parse_packet(const unsigned char *from, struct interface *ifp,
message[2]); message[2]);
goto done; goto done;
} }
if(message[2] == AE_V4OV6 && !has_v4ov6) {
/* We can safely ignore the prefix update that might come
alongside with this TLV, since we ignore every v4-over-v6
TLVs */
debugf("Ignoring v4-over-v6 route (unsupported).\n");
goto done;
}
DO_NTOHS(interval, message + 6); DO_NTOHS(interval, message + 6);
DO_NTOHS(seqno, message + 8); DO_NTOHS(seqno, message + 8);
DO_NTOHS(metric, message + 10); DO_NTOHS(metric, message + 10);
...@@ -1215,6 +1222,8 @@ really_buffer_update(struct buffered *buf, struct interface *ifp, ...@@ -1215,6 +1222,8 @@ really_buffer_update(struct buffered *buf, struct interface *ifp,
if(v4) { if(v4) {
if(!ifp->ipv4) { if(!ifp->ipv4) {
if(!has_v4ov6)
return;
ae = AE_V4OV6; ae = AE_V4OV6;
} else { } else {
ae = AE_IPV4; ae = AE_IPV4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment