summaryrefslogtreecommitdiff
path: root/sysdep/bsd/krt-sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep/bsd/krt-sock.c')
-rw-r--r--sysdep/bsd/krt-sock.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index 0a52cfbd..e56dd616 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -186,6 +186,16 @@ struct ks_msg
memcpy(p, body, (l > sizeof(*p) ? sizeof(*p) : l));\
body += l;}
+static inline void
+sockaddr_fill_dl(struct sockaddr_dl *sa, struct iface *ifa)
+{
+ uint len = OFFSETOF(struct sockaddr_dl, sdl_data);
+ memset(sa, 0, len);
+ sa->sdl_len = len;
+ sa->sdl_family = AF_LINK;
+ sa->sdl_index = ifa->index;
+}
+
static int
krt_send_route(struct krt_proto *p, int cmd, rte *e)
{
@@ -291,11 +301,8 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
{
/* Fallback for all other valid cases */
-#ifdef RTF_CLONING
- if (cmd == RTM_ADD && (i->flags & IF_MULTIACCESS) != IF_MULTIACCESS) /* PTP */
- msg.rtm.rtm_flags |= RTF_CLONING;
-#endif
-
+#if __OpenBSD__
+ /* Keeping temporarily old code for OpenBSD */
struct ifa *addr = (net->n.addr->type == NET_IP4) ? i->addr4 : (i->addr6 ?: i->llv6);
if (!addr)
@@ -304,7 +311,16 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
return -1;
}
- sockaddr_fill(&gate, af, addr->ip, i, 0);
+ /* Embed interface ID to link-local address */
+ ip_addr gw = addr->ip;
+ if (ipa_is_link_local(gw))
+ _I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
+
+ sockaddr_fill(&gate, af, gw, i, 0);
+#else
+ sockaddr_fill_dl(&gate, i);
+#endif
+
msg.rtm.rtm_addrs |= RTA_GATEWAY;
break;
}