Commit 655bdffb authored by Grégoire Henry's avatar Grégoire Henry Committed by Juliusz Chroboczek

Correct neighbours' handling on BSD.

parent c52ee6b4
...@@ -421,7 +421,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -421,7 +421,9 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
return 0; return 0;
if(operation == ROUTE_MODIFY) { if(operation == ROUTE_MODIFY) {
if(metric == KERNEL_INFINITY || newmetric == KERNEL_INFINITY) { /* Do not use ROUTE_MODIFY when changing to a neighbour.
It is the only way to remove the "gateway" flag. */
if(ipv4 && plen == 128 && memcmp(dest, newgate, 16) == 0) {
kernel_route(ROUTE_FLUSH, dest, plen, kernel_route(ROUTE_FLUSH, dest, plen,
gate, ifindex, metric, gate, ifindex, metric,
NULL, 0, 0); NULL, 0, 0);
...@@ -458,7 +460,6 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -458,7 +460,6 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
msg.m_rtm.rtm_index = ifindex; msg.m_rtm.rtm_index = ifindex;
msg.m_rtm.rtm_flags = RTF_UP | RTF_PROTO2; msg.m_rtm.rtm_flags = RTF_UP | RTF_PROTO2;
if(plen == 128) msg.m_rtm.rtm_flags |= RTF_HOST; if(plen == 128) msg.m_rtm.rtm_flags |= RTF_HOST;
msg.m_rtm.rtm_flags |= RTF_GATEWAY;
if(metric == KERNEL_INFINITY) { if(metric == KERNEL_INFINITY) {
msg.m_rtm.rtm_flags |= RTF_BLACKHOLE; msg.m_rtm.rtm_flags |= RTF_BLACKHOLE;
if(ifindex_lo < 0) { if(ifindex_lo < 0) {
...@@ -472,6 +473,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -472,6 +473,16 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
msg.m_rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; msg.m_rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
if(plen != 128) msg.m_rtm.rtm_addrs |= RTA_NETMASK; if(plen != 128) msg.m_rtm.rtm_addrs |= RTA_NETMASK;
#define PUSHEUI(ifindex) \
do { char ifname[IFNAMSIZ]; \
struct sockaddr_dl *sdl = (struct sockaddr_dl*) data; \
if(!if_indextoname((ifindex), ifname)) \
return -1; \
if(get_sdl(sdl, ifname) < 0) \
return -1; \
data = data + ROUNDUP(sdl->sdl_len); \
} while (0)
#define PUSHADDR(src) \ #define PUSHADDR(src) \
do { struct sockaddr_in *sin = (struct sockaddr_in*) data; \ do { struct sockaddr_in *sin = (struct sockaddr_in*) data; \
sin->sin_len = sizeof(struct sockaddr_in); \ sin->sin_len = sizeof(struct sockaddr_in); \
...@@ -497,7 +508,13 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -497,7 +508,13 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
PUSHADDR(dest); PUSHADDR(dest);
if (metric == KERNEL_INFINITY) { if (metric == KERNEL_INFINITY) {
PUSHADDR(**local4); PUSHADDR(**local4);
} else if(plen == 128 && memcmp(dest+12, gate+12, 4) == 0) {
#if defined(RTF_CLONING)
msg.m_rtm.rtm_flags |= RTF_CLONING;
#endif
PUSHEUI(ifindex);
} else { } else {
msg.m_rtm.rtm_flags |= RTF_GATEWAY;
PUSHADDR(gate); PUSHADDR(gate);
} }
if((msg.m_rtm.rtm_addrs & RTA_NETMASK) != 0) { if((msg.m_rtm.rtm_addrs & RTA_NETMASK) != 0) {
...@@ -512,6 +529,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -512,6 +529,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if (metric == KERNEL_INFINITY) { if (metric == KERNEL_INFINITY) {
PUSHADDR6(**local6); PUSHADDR6(**local6);
} else { } else {
msg.m_rtm.rtm_flags |= RTF_GATEWAY;
PUSHADDR6(gate); PUSHADDR6(gate);
} }
if((msg.m_rtm.rtm_addrs & RTA_NETMASK) != 0) { if((msg.m_rtm.rtm_addrs & RTA_NETMASK) != 0) {
...@@ -522,6 +540,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -522,6 +540,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
} }
#undef PUSHEUI
#undef PUSHADDR #undef PUSHADDR
#undef PUSHADDR6 #undef PUSHADDR6
......
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