Commit 86fcf400 authored by Julien Muchembled's avatar Julien Muchembled

RTA_PREFSRC

parent 2631dff6
Pipeline #297 skipped
......@@ -106,6 +106,7 @@ main(int argc, char **argv)
void *vrc;
unsigned int seed;
struct interface *ifp;
unsigned char *addr;
gettime(&now);
......@@ -123,7 +124,7 @@ main(int argc, char **argv)
change_smoothing_half_life(4);
while(1) {
opt = getopt(argc, argv, "m:p:h:H:i:k:A:sruS:d:g:lwz:M:t:T:c:C:DL:I:F");
opt = getopt(argc, argv, "m:p:h:H:i:k:A:sruS:d:g:lwz:M:t:T:c:C:DL:I:FP:");
if(opt < 0)
break;
......@@ -256,6 +257,13 @@ main(int argc, char **argv)
case 'F':
setup = 1;
break;
case 'P':
addr = malloc(16);
rc = parse_address(optarg, addr, &i);
if(rc < 0)
goto usage;
preferred_source[i == AF_INET] = addr;
break;
default:
goto usage;
}
......
......@@ -43,6 +43,7 @@ struct kernel_route {
#define CHANGE_ADDR (1 << 2)
extern int export_table, import_table;
extern unsigned char *preferred_source[2];
int kernel_setup(int setup);
int kernel_setup_socket(int setup);
......
......@@ -52,6 +52,7 @@ THE SOFTWARE.
#include "interface.h"
int export_table = -1, import_table = -1;
unsigned char *preferred_source[2] = {NULL, NULL};
static int old_forwarding = -1;
static int old_ipv4_forwarding = -1;
......@@ -940,45 +941,45 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
rta = RTM_RTA(rtm);
if(ipv4) {
rta = RTA_NEXT(rta, len);
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
rta->rta_type = RTA_DST;
memcpy(RTA_DATA(rta), dest + 12, sizeof(struct in_addr));
} else {
rta = RTA_NEXT(rta, len);
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
rta->rta_type = RTA_DST;
memcpy(RTA_DATA(rta), dest, sizeof(struct in6_addr));
}
#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)); \
} while (0)
ADD_IPARG(RTA_DST, dest);
rta = RTA_NEXT(rta, len);
rta->rta_len = RTA_LENGTH(sizeof(int));
rta->rta_type = RTA_PRIORITY;
if(metric < KERNEL_INFINITY) {
unsigned char *src;
*(int*)RTA_DATA(rta) = metric;
rta = RTA_NEXT(rta, len);
rta->rta_len = RTA_LENGTH(sizeof(int));
rta->rta_type = RTA_OIF;
*(int*)RTA_DATA(rta) = ifindex;
if(ipv4) {
rta = RTA_NEXT(rta, len);
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
rta->rta_type = RTA_GATEWAY;
memcpy(RTA_DATA(rta), gate + 12, sizeof(struct in_addr));
} else {
rta = RTA_NEXT(rta, len);
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
rta->rta_type = RTA_GATEWAY;
memcpy(RTA_DATA(rta), gate, sizeof(struct in6_addr));
}
ADD_IPARG(RTA_GATEWAY, gate);
src = preferred_source[ipv4];
if(src)
ADD_IPARG(RTA_PREFSRC, src);
} else {
*(int*)RTA_DATA(rta) = -1;
}
buf.nh.nlmsg_len = (char*)rta + rta->rta_len - buf.raw;
#undef ADD_IPARG
return netlink_talk(&buf.nh);
}
......
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