summaryrefslogtreecommitdiff
path: root/proto/bgp/attrs.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2013-04-16 17:27:34 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2013-04-16 17:27:34 +0200
commit48bc232f08141d26691237c3d79db587ce16932b (patch)
treea1b58dced547671340b294f47cbe1ee6f385ca0a /proto/bgp/attrs.c
parent9ff5257357d9975654279db17bbc8525583ba1cc (diff)
Implements 'next hop keep' option for BGP.
This option allows to keep the received next hop even in cases when the route is sent to an interface with a different subnet.
Diffstat (limited to 'proto/bgp/attrs.c')
-rw-r--r--proto/bgp/attrs.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 98b2f2c2..c27a4988 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -935,7 +935,8 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
rta->dest != RTD_ROUTER ||
ipa_equal(rta->gw, IPA_NONE) ||
ipa_has_link_scope(rta->gw) ||
- (!p->is_internal && (!p->neigh || (rta->iface != p->neigh->iface))))
+ (!p->is_internal && !p->cf->next_hop_keep &&
+ (!p->neigh || (rta->iface != p->neigh->iface))))
set_next_hop(z, p->source_addr);
else
set_next_hop(z, rta->gw);
@@ -1003,10 +1004,13 @@ bgp_update_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
/* iBGP -> keep next_hop, eBGP multi-hop -> use source_addr,
* eBGP single-hop -> keep next_hop if on the same iface.
* If the next_hop is zero (i.e. link-local), keep only if on the same iface.
+ *
+ * Note that same-iface-check uses iface from route, which is based on gw.
*/
a = ea_find(e->attrs->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
if (a && !p->cf->next_hop_self &&
- ((p->is_internal && ipa_nonzero(*((ip_addr *) a->u.ptr->data))) ||
+ (p->cf->next_hop_keep ||
+ (p->is_internal && ipa_nonzero(*((ip_addr *) a->u.ptr->data))) ||
(p->neigh && (e->attrs->iface == p->neigh->iface))))
{
/* Leave the original next hop attribute, will check later where does it point */