Commit 3646ba98 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Merge remote-tracking branch 'remotes/theo/tobast/v6tethered-reimplem' into v4viav6

parents f82a10e9 a4aebc71
...@@ -22,6 +22,7 @@ This file lists people who have contributed to babeld (in alphabetical order): ...@@ -22,6 +22,7 @@ This file lists people who have contributed to babeld (in alphabetical order):
Matthieu Boutier <boutier at irif dot fr> Matthieu Boutier <boutier at irif dot fr>
Sawssen Hadded <saw dot hadded at gmail dot com> Sawssen Hadded <saw dot hadded at gmail dot com>
Stephane Glondu <steph at glondu dot net> Stephane Glondu <steph at glondu dot net>
Théophile Bastian <theophile dot bastian at ens dot fr>
Thomas Petazzoni <thomas dot petazzoni at free-electrons dot com> Thomas Petazzoni <thomas dot petazzoni at free-electrons dot com>
Toke Høiland-Jørgensen <toke at toke dot dk> Toke Høiland-Jørgensen <toke at toke dot dk>
Vincent Gross <dermiste at screwball-coders dot net> Vincent Gross <dermiste at screwball-coders dot net>
......
...@@ -63,6 +63,7 @@ int debug = 0; ...@@ -63,6 +63,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;
...@@ -151,6 +152,7 @@ main(int argc, char **argv) ...@@ -151,6 +152,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
......
...@@ -1029,6 +1029,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -1029,6 +1029,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);
...@@ -1045,6 +1046,8 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -1045,6 +1046,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
......
...@@ -95,3 +95,10 @@ int gettime(struct timeval *tv); ...@@ -95,3 +95,10 @@ 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 table);
int flush_rule(int prio, int family);
int change_rule(int new_prio, int old_prio, const unsigned char *src, int plen,
int table);
...@@ -943,6 +943,14 @@ kernel_has_ipv6_subtrees(void) ...@@ -943,6 +943,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,
...@@ -956,7 +964,7 @@ kernel_route(int operation, int table, ...@@ -956,7 +964,7 @@ kernel_route(int operation, int table,
struct rtmsg *rtm; struct rtmsg *rtm;
struct rtattr *rta; struct rtattr *rta;
int len = sizeof(buf.raw); int len = sizeof(buf.raw);
int rc, ipv4, use_src = 0; int rc, ipv4, is_v4_over_v6, use_src = 0;
if(!nl_setup) { if(!nl_setup) {
fprintf(stderr,"kernel_route: netlink not initialized.\n"); fprintf(stderr,"kernel_route: netlink not initialized.\n");
...@@ -978,8 +986,7 @@ kernel_route(int operation, int table, ...@@ -978,8 +986,7 @@ kernel_route(int operation, int table,
/* Check that the protocol family is consistent. */ /* Check that the protocol family is consistent. */
if(plen >= 96 && v4mapped(dest)) { if(plen >= 96 && v4mapped(dest)) {
if(!v4mapped(gate) || if(!v4mapped(src)) {
!v4mapped(src)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
...@@ -1018,7 +1025,8 @@ kernel_route(int operation, int table, ...@@ -1018,7 +1025,8 @@ kernel_route(int operation, int table,
} }
ipv4 = v4mapped(gate); ipv4 = v4mapped(dest);
is_v4_over_v6 = ipv4 && !v4mapped(gate);
use_src = !is_default(src, src_plen); use_src = !is_default(src, src_plen);
if(use_src) { if(use_src) {
if(ipv4 || !has_ipv6_subtrees) { if(ipv4 || !has_ipv6_subtrees) {
...@@ -1094,23 +1102,32 @@ kernel_route(int operation, int table, ...@@ -1094,23 +1102,32 @@ kernel_route(int operation, int table,
rta->rta_type = RTA_OIF; rta->rta_type = RTA_OIF;
*(int*)RTA_DATA(rta) = ifindex; *(int*)RTA_DATA(rta) = ifindex;
#define ADD_IPARG(type, addr) \ #define ADD_IPARG(type, addr) \
do if(ipv4) { \ do { \
rta = RTA_NEXT(rta, len); \ rta = RTA_NEXT(rta, len); \
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr)); \ rta->rta_type = type; \
rta->rta_type = type; \ if(v4mapped(addr)) { \
memcpy(RTA_DATA(rta), addr + 12, sizeof(struct in_addr)); \ rta->rta_len = RTA_LENGTH(sizeof(struct in_addr)); \
} else { \ memcpy(RTA_DATA(rta), addr + 12, sizeof(struct in_addr)); \
rta = RTA_NEXT(rta, len); \ } else { \
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); \ if(type == RTA_VIA) { \
rta->rta_type = type; \ rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr) + 2); \
memcpy(RTA_DATA(rta), addr, sizeof(struct in6_addr)); \ *((sa_family_t*) RTA_DATA(rta)) = AF_INET6; \
memcpy(RTA_DATA(rta) + 2, addr, sizeof(struct in6_addr)); \
} else { \
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); \
memcpy(RTA_DATA(rta), addr, sizeof(struct in6_addr)); \
} \
} \
} while (0) } while (0)
ADD_IPARG(RTA_GATEWAY, gate); if(is_v4_over_v6)
ADD_IPARG(RTA_VIA, gate);
else
ADD_IPARG(RTA_GATEWAY, gate);
if(pref_src) if(pref_src)
ADD_IPARG(RTA_PREFSRC, pref_src); ADD_IPARG(RTA_PREFSRC, pref_src);
#undef ADD_IPARG #undef ADD_IPARG
} else { } else {
*(int*)RTA_DATA(rta) = -1; *(int*)RTA_DATA(rta) = -1;
......
...@@ -395,6 +395,12 @@ kernel_has_ipv6_subtrees(void) ...@@ -395,6 +395,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,
......
This diff is collapsed.
...@@ -47,6 +47,13 @@ THE SOFTWARE. ...@@ -47,6 +47,13 @@ THE SOFTWARE.
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */ #define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
#define SUBTLV_SOURCE_PREFIX 128 /* Source-specific routing. */ #define SUBTLV_SOURCE_PREFIX 128 /* Source-specific routing. */
/* Address encodings */
#define AE_WILDCARD 0
#define AE_IPV4 1
#define AE_IPV6 2
#define AE_IPV6_LOCAL 3
#define AE_V4OV6 4
extern unsigned short myseqno; extern unsigned short myseqno;
extern struct timeval seqno_time; extern struct timeval seqno_time;
......
...@@ -502,6 +502,12 @@ v4tov6(unsigned char *dst, const unsigned char *src) ...@@ -502,6 +502,12 @@ v4tov6(unsigned char *dst, const unsigned char *src)
memcpy(dst + 12, src, 4); memcpy(dst + 12, src, 4);
} }
int
ae_is_v4(int ae)
{
return ae == 1 || ae == 4;
}
int int
daemonise() daemonise()
{ {
......
...@@ -100,6 +100,7 @@ int wait_for_fd(int direction, int fd, int msecs); ...@@ -100,6 +100,7 @@ int wait_for_fd(int direction, int fd, int msecs);
int martian_prefix(const unsigned char *prefix, int plen) ATTRIBUTE ((pure)); int martian_prefix(const unsigned char *prefix, int plen) ATTRIBUTE ((pure));
int linklocal(const unsigned char *address) ATTRIBUTE ((pure)); int linklocal(const unsigned char *address) ATTRIBUTE ((pure));
int v4mapped(const unsigned char *address) ATTRIBUTE ((pure)); int v4mapped(const unsigned char *address) ATTRIBUTE ((pure));
int ae_is_v4(int ae) ATTRIBUTE ((pure));
void v4tov6(unsigned char *dst, const unsigned char *src); void v4tov6(unsigned char *dst, const unsigned char *src);
int daemonise(void); int daemonise(void);
int set_src_prefix(unsigned char *src_addr, unsigned char *src_plen); int set_src_prefix(unsigned char *src_addr, unsigned char *src_plen);
......
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