]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Use link-local addresses in recursive next hops for IPv6 BGP.
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 28 Jul 2010 09:45:35 +0000 (11:45 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 28 Jul 2010 09:45:35 +0000 (11:45 +0200)
nest/route.h
nest/rt-table.c
proto/bgp/packets.c

index 45b78e38df0c915598b8a6f13cc4f2561542170e..4dd437501f8f5fb778a8ef67d65295c04a50135c 100644 (file)
@@ -163,7 +163,9 @@ struct hostcache {
 
 struct hostentry {
   node ln;
-  ip_addr addr;                                /* IP of host, part of key */
+  ip_addr addr;                                /* IP address of host, part of key */
+  ip_addr link;                                /* (link-local) IP address of host, used as gw
+                                          if host is directly attached */
   struct rtable *tab;                  /* Dependent table, part of key*/
   struct hostentry *next;              /* Next in hash chain */
   unsigned hash_key;                   /* Hash key */
@@ -386,7 +388,7 @@ static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); }
 void rta_dump(rta *);
 void rta_dump_all(void);
 void rta_show(struct cli *, rta *, ea_list *);
-void rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw);
+void rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll);
 
 /*
  * rta_set_recursive_next_hop() acquires hostentry from hostcache and
index af1a920c25d3b7d9077912b00a660ed1154a6877..1f84e975f7add465236a085b767e4db01af40106 100644 (file)
@@ -1358,11 +1358,12 @@ hc_resize(struct hostcache *hc, unsigned new_order)
 }
 
 static struct hostentry *
-hc_new_hostentry(struct hostcache *hc, ip_addr a, rtable *dep, unsigned k)
+hc_new_hostentry(struct hostcache *hc, ip_addr a, ip_addr ll, rtable *dep, unsigned k)
 {
   struct hostentry *he = sl_alloc(hc->slab);
 
   he->addr = a;
+  he->link = ll;
   he->tab = dep;
   he->hash_key = k;
   he->uc = 0;
@@ -1475,9 +1476,9 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
            }
          else
            {
-             /* The host is directly reachable, us it as a gateway */
+             /* The host is directly reachable, use link as a gateway */
              he->iface = a->iface;
-             he->gw = he->addr;
+             he->gw = he->link;
              he->dest = RTD_ROUTER;
            }
        }
@@ -1531,7 +1532,7 @@ rt_update_hostcache(rtable *tab)
 }
 
 static struct hostentry *
-rt_find_hostentry(rtable *tab, ip_addr a, rtable *dep)
+rt_find_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
 {
   struct hostentry *he;
 
@@ -1544,15 +1545,15 @@ rt_find_hostentry(rtable *tab, ip_addr a, rtable *dep)
     if (ipa_equal(he->addr, a) && (he->tab == dep))
       return he;
 
-  he = hc_new_hostentry(hc, a, dep, k);
+  he = hc_new_hostentry(hc, a, ll, dep, k);
   rt_update_hostentry(tab, he);
   return he;
 }
 
 void
-rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw)
+rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll)
 {
-  rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, dep));
+  rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, *ll, dep));
 }
 
 /*
index ba43cd283b9559e60f2f0bf643ade84b17764906..632c564e1a012cfa7077a3c21fe59c3de39e16ba 100644 (file)
@@ -805,11 +805,17 @@ static inline int
 bgp_set_next_hop(struct bgp_proto *p, rta *a)
 {
   struct eattr *nh = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
-  ip_addr nexthop = *(ip_addr *) nh->u.ptr->data;
+  ip_addr *nexthop = (ip_addr *) nh->u.ptr->data;
+
+#ifdef IPV6
+  int second = (nh->u.ptr->length == NEXT_HOP_LENGTH);
+#else
+  int second = 0;
+#endif
 
   if (p->cf->gw_mode == GW_DIRECT)
     {
-      neighbor *ng = neigh_find(&p->p, &nexthop, 0) ? : p->neigh;
+      neighbor *ng = neigh_find(&p->p, nexthop, 0) ? : p->neigh;
       if (ng->scope == SCOPE_HOST)
        return 0;
 
@@ -819,7 +825,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
       a->hostentry = NULL;
     }
   else /* GW_RECURSIVE */
-    rta_set_recursive_next_hop(p->p.table, a, p->igp_table, &nexthop);
+    rta_set_recursive_next_hop(p->p.table, a, p->igp_table, nexthop, nexthop + second);
 
   return 1;
 }