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):
Matthieu Boutier <boutier at irif dot fr>
Sawssen Hadded <saw dot hadded at gmail dot com>
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>
Toke Høiland-Jørgensen <toke at toke dot dk>
Vincent Gross <dermiste at screwball-coders dot net>
......
......@@ -63,6 +63,7 @@ int debug = 0;
int link_detect = 0;
int all_wireless = 0;
int has_ipv6_subtrees = 0;
int has_v4ov6 = 0;
int default_wireless_hello_interval = -1;
int default_wired_hello_interval = -1;
int resend_delay = -1;
......@@ -151,6 +152,7 @@ main(int argc, char **argv)
protocol_port = 6696;
change_smoothing_half_life(4);
has_ipv6_subtrees = kernel_has_ipv6_subtrees();
has_v4ov6 = kernel_has_v4ov6();
while(1) {
opt = getopt(argc, argv,
......
......@@ -92,6 +92,7 @@ extern const char *logfile, *pidfile, *state_file;
extern int link_detect;
extern int all_wireless;
extern int has_ipv6_subtrees;
extern int has_v4ov6;
extern unsigned char myid[8];
extern int have_id;
......
......@@ -200,6 +200,11 @@ This specifies whether to use native source-specific IPv6 forwarding
rather than multiple routing tables. The default is chosen automatically
depending on the kernel version.
.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"
This specifies the debugging level, and is equivalent to the command-line
option
......
......@@ -1029,6 +1029,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
strcmp(token, "daemonise") == 0 ||
strcmp(token, "skip-kernel-setup") == 0 ||
strcmp(token, "ipv6-subtrees") == 0 ||
strcmp(token, "v4-over-v6") == 0 ||
strcmp(token, "reflect-kernel-metric") == 0) {
int b;
c = getbool(c, &b, gnc, closure);
......@@ -1045,6 +1046,8 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
skip_kernel_setup = b;
else if(strcmp(token, "ipv6-subtrees") == 0)
has_ipv6_subtrees = b;
else if(strcmp(token, "v4-over-v6") == 0)
has_v4ov6 = b;
else if(strcmp(token, "reflect-kernel-metric") == 0)
reflect_kernel_metric = b;
else
......
......@@ -95,3 +95,10 @@ int gettime(struct timeval *tv);
int read_random_bytes(void *buf, int len);
int kernel_older_than(const char *sysname, int version, int sub_version);
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)
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
kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen,
......@@ -956,7 +964,7 @@ kernel_route(int operation, int table,
struct rtmsg *rtm;
struct rtattr *rta;
int len = sizeof(buf.raw);
int rc, ipv4, use_src = 0;
int rc, ipv4, is_v4_over_v6, use_src = 0;
if(!nl_setup) {
fprintf(stderr,"kernel_route: netlink not initialized.\n");
......@@ -978,8 +986,7 @@ kernel_route(int operation, int table,
/* Check that the protocol family is consistent. */
if(plen >= 96 && v4mapped(dest)) {
if(!v4mapped(gate) ||
!v4mapped(src)) {
if(!v4mapped(src)) {
errno = EINVAL;
return -1;
}
......@@ -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);
if(use_src) {
if(ipv4 || !has_ipv6_subtrees) {
......@@ -1094,23 +1102,32 @@ kernel_route(int operation, int table,
rta->rta_type = RTA_OIF;
*(int*)RTA_DATA(rta) = ifindex;
#define ADD_IPARG(type, addr) \
do if(ipv4) { \
rta = RTA_NEXT(rta, len); \
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr)); \
rta->rta_type = type; \
memcpy(RTA_DATA(rta), addr + 12, sizeof(struct in_addr)); \
} else { \
rta = RTA_NEXT(rta, len); \
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); \
rta->rta_type = type; \
memcpy(RTA_DATA(rta), addr, sizeof(struct in6_addr)); \
#define ADD_IPARG(type, addr) \
do { \
rta = RTA_NEXT(rta, len); \
rta->rta_type = type; \
if(v4mapped(addr)) { \
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr)); \
memcpy(RTA_DATA(rta), addr + 12, sizeof(struct in_addr)); \
} else { \
if(type == RTA_VIA) { \
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr) + 2); \
*((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)
ADD_IPARG(RTA_GATEWAY, gate);
if(is_v4_over_v6)
ADD_IPARG(RTA_VIA, gate);
else
ADD_IPARG(RTA_GATEWAY, gate);
if(pref_src)
ADD_IPARG(RTA_PREFSRC, pref_src);
#undef ADD_IPARG
} else {
*(int*)RTA_DATA(rta) = -1;
......
......@@ -395,6 +395,12 @@ kernel_has_ipv6_subtrees(void)
return 0;
}
int
kernel_has_v4ov6(void)
{
return 0;
}
int
kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen,
......
This diff is collapsed.
......@@ -47,6 +47,13 @@ THE SOFTWARE.
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
#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 struct timeval seqno_time;
......
......@@ -502,6 +502,12 @@ v4tov6(unsigned char *dst, const unsigned char *src)
memcpy(dst + 12, src, 4);
}
int
ae_is_v4(int ae)
{
return ae == 1 || ae == 4;
}
int
daemonise()
{
......
......@@ -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 linklocal(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);
int daemonise(void);
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