]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Better selection of link-local NLRI addresses, at least for our own
authorMartin Mares <mj@ucw.cz>
Sat, 22 Feb 2003 22:47:45 +0000 (22:47 +0000)
committerMartin Mares <mj@ucw.cz>
Sat, 22 Feb 2003 22:47:45 +0000 (22:47 +0000)
address. Need to do it better for the other neighbors -- the current
solution works only if they use the standard 64+64 global addresses
and the interface identifier in lower 64 bits is the same as for the
link-scope addresses.

proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c

index f6cbed4c2edb67426ecc5bd469ecff72922d0649..7069d982afc23ad7723a7d26462928b246613f34 100644 (file)
@@ -434,6 +434,19 @@ bgp_start_neighbor(struct bgp_proto *p)
 {
   p->local_addr = p->neigh->iface->addr->ip;
   DBG("BGP: local=%I remote=%I\n", p->local_addr, p->next_hop);
+#ifdef IPV6
+  {
+    struct ifa *a;
+    p->local_link = ipa_or(ipa_build(0xfe80,0,0,0), ipa_and(p->local_addr, ipa_build(0,0,~0,~0)));
+    WALK_LIST(a, p->neigh->iface->addrs)
+      if (a->scope == SCOPE_LINK)
+        {
+         p->local_link = a->ip;
+         break;
+       }
+    DBG("BGP: Selected link-level address %I\n", p->local_link);
+  }
+#endif
   bgp_initiate(p);
 }
 
index 03f47f99af85a07187b273ba771b40029cd0a7e0..6519db856177ce98a849c057f86ad731187265aa 100644 (file)
@@ -74,6 +74,7 @@ struct bgp_proto {
 #ifdef IPV6
   byte *mp_reach_start, *mp_unreach_start; /* Multiprotocol BGP attribute notes */
   unsigned mp_reach_len, mp_unreach_len;
+  ip_addr local_link;                  /* Link-level version of local_addr */
 #endif
 };
 
index bf893436792ad9a5ed435d1430cd81b7f6da1e40..03b221172f3828e532108135fedf46aa66d44bf5 100644 (file)
@@ -193,20 +193,27 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
          nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
          ASSERT(nh);
          ip = *(ip_addr *) nh->u.ptr->data;
+         is_ll = 0;
          if (ipa_equal(ip, p->local_addr))
-           is_ll = 1;
+           {
+             is_ll = 1;
+             ip_ll = p->local_link;
+           }
          else
            {
              n = neigh_find(&p->p, &ip, 0);
              if (n && n->iface == p->neigh->iface)
-               is_ll = 1;
-             else
-               is_ll = 0;
+               {
+                 /* FIXME: We are assuming the global scope addresses use the lower 64 bits
+                  * as an interface identifier which hasn't necessarily to be true.
+                  */
+                 is_ll = 1;
+                 ip_ll = ipa_or(ipa_build(0xfe800000,0,0,0), ipa_and(ip, ipa_build(0,0,~0,~0)));
+               }
            }
          if (is_ll)
            {
              *tmp++ = 32;
-             ip_ll = ipa_or(ipa_build(0xfe80,0,0,0), ipa_and(ip, ipa_build(0,0,~0,~0)));
              ipa_hton(ip);
              memcpy(tmp, &ip, 16);
              ipa_hton(ip_ll);