]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes handling of 'next hop self' and 'source address' configuration
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 28 Apr 2009 16:11:56 +0000 (18:11 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 28 Apr 2009 16:11:56 +0000 (18:11 +0200)
options.

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

index a015c2b379f19cbfaa1b80d7836f48cc0241a5cc..9a247dec90046085289c60ef9833815f62697afd 100644 (file)
@@ -790,12 +790,7 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
   if (p->cf->next_hop_self ||
       !p->is_internal ||
       rta->dest != RTD_ROUTER)
-    {
-      if (ipa_nonzero(p->cf->source_addr))
-        *(ip_addr *)z = p->cf->source_addr;
-      else
-        *(ip_addr *)z = p->local_addr;
-    }
+    *(ip_addr *)z = p->source_addr;
   else
     *(ip_addr *)z = e->attrs->gw;
 
@@ -860,14 +855,14 @@ bgp_update_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
     }
 
   a = ea_find(e->attrs->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
-  if (a && (p->is_internal || (!p->is_internal && e->attrs->iface == p->neigh->iface)))
+  if (a && !p->cf->next_hop_self && (p->is_internal || (!p->is_internal && e->attrs->iface == p->neigh->iface)))
     {
       /* Leave the original next hop attribute, will check later where does it point */
     }
   else
     {
       /* Need to create new one */
-      bgp_attach_attr_ip(attrs, pool, BA_NEXT_HOP, p->local_addr);
+      bgp_attach_attr_ip(attrs, pool, BA_NEXT_HOP, p->source_addr);
     }
 
   if (rr)
index 41c8d5339ac168536e323d25c0d07788a3971080..a0bc89238bd215998ca5902e4bcfbe68f5dbb440 100644 (file)
@@ -500,10 +500,7 @@ bgp_connect(struct bgp_proto *p)   /* Enter Connect state and start establishing c
   DBG("BGP: Connecting\n");
   s = sk_new(p->p.pool);
   s->type = SK_TCP_ACTIVE;
-  if (ipa_nonzero(p->cf->source_addr))
-    s->saddr = p->cf->source_addr;
-  else
-    s->saddr = p->local_addr;
+  s->saddr = p->source_addr;
   s->daddr = p->cf->remote_ip;
   s->dport = BGP_PORT;
   s->ttl = p->cf->multihop ? : 1;
@@ -609,7 +606,9 @@ static void
 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);
+  p->source_addr = ipa_nonzero(p->cf->source_addr) ? p->cf->source_addr : p->local_addr;
+
+  DBG("BGP: local=%I remote=%I\n", p->source_addr, p->next_hop);
 #ifdef IPV6
   {
     struct ifa *a;
index d5448a68947b096ec93e866bd121204e1fc40320..83ed9c7503b6f84b52a67129b795cb571d2d32c9 100644 (file)
@@ -79,6 +79,7 @@ struct bgp_proto {
   ip_addr next_hop;                    /* Either the peer or multihop_via */
   struct neighbor *neigh;              /* Neighbor entry corresponding to next_hop */
   ip_addr local_addr;                  /* Address of the local end of the link to next_hop */
+  ip_addr source_addr;                 /* Address used as advertised next hop, usually local_addr */
   struct event *event;                 /* Event for respawning and shutting process */
   struct bgp_bucket **bucket_hash;     /* Hash table of attribute buckets */
   unsigned int hash_size, hash_count, hash_limit;
index 1370ee709d438efd0f1d176198ecd6c25beb6585..93cabbec83242eb8471c2b357a8bc6eadaf3b04a 100644 (file)
@@ -293,7 +293,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
          ASSERT(nh);
          ip = *(ip_addr *) nh->u.ptr->data;
          is_ll = 0;
-         if (ipa_equal(ip, p->local_addr))
+         if (ipa_equal(ip, p->source_addr))
            {
              is_ll = 1;
              ip_ll = p->local_link;