]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes related to routes with link-local gw on BSD.
authorOndrej Zajicek <santiago@crfreenet.org>
Sat, 3 Apr 2010 09:42:18 +0000 (11:42 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Sat, 3 Apr 2010 09:42:18 +0000 (11:42 +0200)
sysdep/bsd/krt-sock.c

index 1a2cc9f27e9d8cd9c93e0ef53a7bfb3b696a1e25..a0d7c360327fa42381636cd1f3303d34fb87dba6 100644 (file)
@@ -83,13 +83,10 @@ krt_sock_send(int cmd, rte *e)
   struct ks_msg msg;
   char *body = (char *)msg.buf;
   sockaddr gate, mask, dst;
+  ip_addr gw;
 
   DBG("krt-sock: send %I/%d via %I\n", net->n.prefix, net->n.pxlen, a->gw);
 
-  fill_in_sockaddr(&dst, net->n.prefix, 0);
-  fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), 0);
-  fill_in_sockaddr(&gate, a->gw, 0);
-
   bzero(&msg,sizeof (struct rt_msghdr));
   msg.rtm.rtm_version = RTM_VERSION;
   msg.rtm.rtm_type = cmd;
@@ -133,6 +130,18 @@ krt_sock_send(int cmd, rte *e)
     }
   }
 
+  gw = a->gw;
+
+#ifdef IPV6
+  /* Embed interface ID to link-local address */
+  if (ipa_has_link_scope(gw))
+    _I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
+#endif
+
+  fill_in_sockaddr(&dst, net->n.prefix, 0);
+  fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), 0);
+  fill_in_sockaddr(&gate, gw, 0);
+
   switch (a->dest)
   {
     case RTD_ROUTER:
@@ -359,6 +368,12 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
     a.dest = RTD_ROUTER;
     a.gw = igate;
 
+#ifdef IPV6
+    /* Clean up embedded interface ID returned in link-local address */
+    if (ipa_has_link_scope(a.gw))
+      _I0(a.gw) = 0xfe800000;
+#endif
+
     ng = neigh_find2(&p->p, &a.gw, a.iface, 0);
     if (!ng || (ng->scope == SCOPE_HOST))
       {
@@ -515,13 +530,11 @@ krt_read_addr(struct ks_msg *msg)
   }
   ifa.scope = scope & IADDR_SCOPE_MASK;
 
-  /* BSD returns some scope/interface ID as a part of link-local address */
-  if (scope == (IADDR_HOST | SCOPE_LINK))
-  {
-    /* Clean up that */
+#ifdef IPV6
+  /* Clean up embedded interface ID returned in link-local address */
+  if (ipa_has_link_scope(ifa.ip))
     _I0(ifa.ip) = 0xfe800000;
-    _I1(ifa.ip) = 0x00000000;
-  }
+#endif
 
   if (iface->flags & IF_MULTIACCESS)
     ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));