]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: implement "next-hop-self all"
authorTimo Teräs <timo.teras@iki.fi>
Thu, 24 Apr 2014 07:22:37 +0000 (10:22 +0300)
committerTimo Teräs <timo.teras@iki.fi>
Wed, 25 Jun 2014 18:20:20 +0000 (21:20 +0300)
As specified in:
http://www.cisco.com/c/en/us/td/docs/ios-xml/ios/iproute_bgp/command/irg-cr-book/bgp-m1.html#wp4972925610

This allows overriding next-hop for ibgp learned routes on an
RR for reflected routes.

Especially useful for using iBGP in DMVPN setups. See:
http://blog.ipspace.net/2014/04/changes-in-ibgp-next-hop-processing.html

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
bgpd/bgp_route.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h
doc/bgpd.texi

index f421ca5eb25979ca6a6104334f13e3f487eae55c..232a6a1c38febaf0103d0f259b5064e7e1101cd4 100644 (file)
@@ -976,7 +976,8 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
     }
 
   /* next-hop-set */
-  if (transparent || reflect
+  if (transparent
+      || (reflect && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF_ALL))
       || (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
          && ((p->family == AF_INET && attr->nexthop.s_addr)
 #ifdef HAVE_IPV6
index 3c6973b0b38919a4fc3c6a86bf6d050d6d9f2a9e..a818fe7a86530f8dedcbc69fe5bcf1a993dfe38e 100644 (file)
@@ -2093,25 +2093,41 @@ DEFUN (no_neighbor_capability_orf_prefix,
 /* neighbor next-hop-self. */
 DEFUN (neighbor_nexthop_self,
        neighbor_nexthop_self_cmd,
-       NEIGHBOR_CMD2 "next-hop-self",
+       NEIGHBOR_CMD2 "next-hop-self {all}",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Disable the next hop calculation for this neighbor\n")
+       "Disable the next hop calculation for this neighbor\n"
+       "Apply also to ibgp-learned routes when acting as a route reflector\n")
 {
-  return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
-                              bgp_node_safi (vty), PEER_FLAG_NEXTHOP_SELF);
+  u_int32_t flags = PEER_FLAG_NEXTHOP_SELF, unset = 0;
+  int rc;
+
+  /* Check if "all" is specified */
+  if (argv[1] != NULL)
+    flags |= PEER_FLAG_NEXTHOP_SELF_ALL;
+  else
+    unset |= PEER_FLAG_NEXTHOP_SELF_ALL;
+
+  rc = peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+                            bgp_node_safi (vty), flags);
+  if ( rc == CMD_SUCCESS && unset )
+    rc = peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+                                bgp_node_safi (vty), unset);
+  return rc;
 }
 
 DEFUN (no_neighbor_nexthop_self,
        no_neighbor_nexthop_self_cmd,
-       NO_NEIGHBOR_CMD2 "next-hop-self",
+       NO_NEIGHBOR_CMD2 "next-hop-self {all}",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Disable the next hop calculation for this neighbor\n")
+       "Disable the next hop calculation for this neighbor\n"
+       "Apply also to ibgp-learned routes when acting as a route reflector\n")
 {
   return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
-                                bgp_node_safi (vty), PEER_FLAG_NEXTHOP_SELF);
+                                bgp_node_safi (vty),
+                                PEER_FLAG_NEXTHOP_SELF|PEER_FLAG_NEXTHOP_SELF_ALL);
 }
 
 /* neighbor remove-private-AS. */
index 19b96fa93a8e0bfa3aba0f1c8f2f5fac18cba11a..4d374cc19a7607157239bc79f5f67a81d7b95fc7 100644 (file)
@@ -2355,6 +2355,7 @@ static const struct peer_flag_action peer_af_flag_action_list[] =
     { PEER_FLAG_ORF_PREFIX_SM,            1, peer_change_reset },
     { PEER_FLAG_ORF_PREFIX_RM,            1, peer_change_reset },
     { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED,  0, peer_change_reset_out },
+    { PEER_FLAG_NEXTHOP_SELF_ALL,         1, peer_change_reset_out },
     { 0, 0, 0 }
   };
 
@@ -4990,7 +4991,9 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
   /* Nexthop self. */
   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
       && ! peer->af_group[afi][safi])
-    vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
+    vty_out (vty, " neighbor %s next-hop-self%s%s", addr,
+            peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF_ALL) ?
+            " all" : "", VTY_NEWLINE);
 
   /* Remove private AS. */
   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
index a1b1273ba5de730a467b7a49ff0a5cb136ea7f0e..eae803de1435f72f6ef4134df64147e04d9fa1e4 100644 (file)
@@ -412,6 +412,7 @@ struct peer
 #define PEER_FLAG_MAX_PREFIX                (1 << 14) /* maximum prefix */
 #define PEER_FLAG_MAX_PREFIX_WARNING        (1 << 15) /* maximum prefix warning-only */
 #define PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED   (1 << 16) /* leave link-local nexthop unchanged */
+#define PEER_FLAG_NEXTHOP_SELF_ALL          (1 << 17) /* next-hop-self all */
 
   /* MD5 password */
   char *password;
index cb9789bdb2b5f19693fd0c5d637f5042b5290e55..de709707a7d5de86d3e0e435e150ffba45bafb9f 100644 (file)
@@ -299,10 +299,12 @@ This command is deprecated and may be removed in a future release. Its
 use should be avoided.
 @end deffn
 
-@deffn {BGP} {neighbor @var{peer} next-hop-self} {}
-@deffnx {BGP} {no neighbor @var{peer} next-hop-self} {}
+@deffn {BGP} {neighbor @var{peer} next-hop-self [all]} {}
+@deffnx {BGP} {no neighbor @var{peer} next-hop-self [all]} {}
 This command specifies an announced route's nexthop as being equivalent
-to the address of the bgp router.
+to the address of the bgp router if it is learned via eBGP.
+If the optional keyword @code{all} is specified the modifiation is done
+also for routes learned via iBGP.
 @end deffn
 
 @deffn {BGP} {neighbor @var{peer} update-source @var{<ifname|address>}} {}