From ad440a570b37e8674ef35f3a18df48f0eb2579eb Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 28 Apr 2009 18:11:56 +0200 Subject: [PATCH] Fixes handling of 'next hop self' and 'source address' configuration options. --- proto/bgp/attrs.c | 11 +++-------- proto/bgp/bgp.c | 9 ++++----- proto/bgp/bgp.h | 1 + proto/bgp/packets.c | 2 +- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index a015c2b3..9a247dec 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -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) diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 41c8d533..a0bc8923 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -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; diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index d5448a68..83ed9c75 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -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; diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 1370ee70..93cabbec 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -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;