]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements 'next hop keep' option for BGP.
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 16 Apr 2013 15:27:34 +0000 (17:27 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 16 Apr 2013 15:27:34 +0000 (17:27 +0200)
This option allows to keep the received next hop even in cases when
the route is sent to an interface with a different subnet.

doc/bird.sgml
proto/bgp/attrs.c
proto/bgp/bgp.h
proto/bgp/config.Y

index 8e5641e01c0b01801d24e69f5b4471840e194894..300a71f3f9264737c051bc9739adb16baa195548 100644 (file)
@@ -1329,6 +1329,11 @@ for each neighbor using the following configuration parameters:
        circumvent misconfigurations of other routers.  Default:
        disabled.
 
+       <tag>next hop keep</tag> Forward the received Next Hop
+       attribute even in situations where the local address should be
+       used instead, like when the route is sent to an interface with
+       a different subnet. Default: disabled.
+
        <tag>missing lladdr self|drop|ignore</tag>Next Hop attribute
        in BGP-IPv6 sometimes contains just the global IPv6 address,
        but sometimes it has to contain both global and link-local
index 98b2f2c20599451a2330e8589d01c79c20befbe9..c27a49880fe0840ca69267d8b8491da7893a4c1a 100644 (file)
@@ -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 */
index c3adf254ad35df25d1abba43d2ad55550c06a2a0..13c7fd80655f990ca4f9af724573274842f8d311 100644 (file)
@@ -24,6 +24,7 @@ struct bgp_config {
   int multihop;                                /* Number of hops if multihop */
   int ttl_security;                    /* Enable TTL security [RFC5082] */
   int next_hop_self;                   /* Always set next hop to local IP address */
+  int next_hop_keep;                   /* Do not touch next hop attribute */
   int missing_lladdr;                  /* What we will do when we don' know link-local addr, see MLL_* */
   int gw_mode;                         /* How we compute route gateway from next_hop attr, see GW_* */
   int compare_path_lengths;            /* Use path lengths when selecting best route */
index 8b80d7fdc696979fdfc735f8b5bc99075babf62a..d5e5aacadc38a94a265b95306ec35fd103b2051a 100644 (file)
@@ -76,7 +76,8 @@ bgp_proto:
  | bgp_proto KEEPALIVE TIME expr ';' { BGP_CFG->keepalive_time = $4; }
  | bgp_proto MULTIHOP ';' { BGP_CFG->multihop = 64; }
  | bgp_proto MULTIHOP expr ';' { BGP_CFG->multihop = $3; if (($3<1) || ($3>255)) cf_error("Multihop must be in range 1-255"); }
- | bgp_proto NEXT HOP SELF ';' { BGP_CFG->next_hop_self = 1; }
+ | bgp_proto NEXT HOP SELF ';' { BGP_CFG->next_hop_self = 1; BGP_CFG->next_hop_keep = 0; }
+ | bgp_proto NEXT HOP KEEP ';' { BGP_CFG->next_hop_keep = 1; BGP_CFG->next_hop_self = 0; }
  | bgp_proto MISSING LLADDR SELF ';' { BGP_CFG->missing_lladdr = MLL_SELF; }
  | bgp_proto MISSING LLADDR DROP ';' { BGP_CFG->missing_lladdr = MLL_DROP; }
  | bgp_proto MISSING LLADDR IGNORE ';' { BGP_CFG->missing_lladdr = MLL_IGNORE; }