]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Adds some options and documentation related to recursive next hops.
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 13 Jul 2010 10:48:23 +0000 (12:48 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 13 Jul 2010 10:48:23 +0000 (12:48 +0200)
doc/bird.sgml
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/config.Y
proto/bgp/packets.c

index 82ff630f39821f43a39d1cf55e46e970c1079d3b..cd6d4138b58164da56f1a9bac90f7af946559016 100644 (file)
@@ -1028,6 +1028,24 @@ for each neighbor using the following configuration parameters:
        is configured as a route server (option <cf/rs client/), in
        that case default is <cf/drop/, because route servers usually
        does not forward packets ifselves.
+
+       <tag>gateway direct|recursive</tag>For received routes, their
+       <cf/gw/ (immediate next hop) attribute is computed from
+       received <cf/bgp_next_hop/ attribute. This option specifies
+       how it is computed. Direct mode means that the IP address from
+       <cf/bgp_next_hop/ is used if it is directly reachable,
+       otherwise the neighbor IP address is used. Recursive mode
+       means that the gateway is computed by a IGP routing table
+       lookup for the IP address from <cf/bgp_next_hop/. Recursive
+       mode is the behavior specified by the BGP standard. Direct
+       mode is simpler, does not require any routes in a routing
+       table, and was used in older versions of BIRD, but does not
+       handle well nontrivial iBGP setups and multihop. Default:
+       <cf/direct/ for singlehop eBGP, <cf/recursive/ otherwise.
+
+       <tag>igp table <m/name/</tag> Specifies a table that is used
+       in a recursive gateway mode for computing <cf/gw/ attributes.
+       Default: the same as the table BGP is connected to.
        
        <tag>password <m/string/</tag> Use this password for MD5 authentication
        of BGP sessions. Default: no authentication. Password has to be set by
index 3aa8845ed0d38abcac0e10a1fbd6024ff5073b86..1f723aeeb0dc17a4cf11bbbfbd9404d5f8ea0bc1 100644 (file)
@@ -951,6 +951,8 @@ bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code)
 void
 bgp_check(struct bgp_config *c)
 {
+  int internal = (c->local_as == c->remote_as);
+
   if (!c->local_as)
     cf_error("Local AS number must be set");
 
@@ -960,15 +962,22 @@ bgp_check(struct bgp_config *c)
   if (!(c->capabilities && c->enable_as4) && (c->remote_as > 0xFFFF))
     cf_error("Neighbor AS number out of range (AS4 not available)");
 
-  if ((c->local_as != c->remote_as) && (c->rr_client))
+  if (!internal && c->rr_client)
     cf_error("Only internal neighbor can be RR client");
 
-  if ((c->local_as == c->remote_as) && (c->rs_client))
+  if (internal && c->rs_client)
     cf_error("Only external neighbor can be RS client");
 
+  if (c->multihop && (c->gw_mode == GW_DIRECT))
+    cf_error("Multihop BGP cannot use direct gateway mode");
+
   /* Different default based on rs_client */
-  if (c->missing_lladdr == 0)
+  if (!c->missing_lladdr)
     c->missing_lladdr = c->rs_client ? MLL_DROP : MLL_SELF;
+
+  /* Different default for gw_mode */
+  if (!c->gw_mode)
+    c->gw_mode = (c->multihop || internal) ? GW_RECURSIVE : GW_DIRECT;
 }
 
 static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
index 160aa3db8b9eea75ffd4004c3e15df991602808b..6bb1d6e5dc986222895b6e916b7fe9d1966c8d51 100644 (file)
@@ -23,6 +23,7 @@ struct bgp_config {
   ip_addr source_addr;                 /* Source address to use */
   int next_hop_self;                   /* Always set next hop to local IP address */
   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 */
   int prefer_older;                    /* Prefer older routes according to RFC 5004 */
   u32 default_local_pref;              /* Default value for LOCAL_PREF attribute */
@@ -53,6 +54,9 @@ struct bgp_config {
 #define MLL_DROP 2
 #define MLL_IGNORE 3
 
+#define GW_DIRECT 1
+#define GW_RECURSIVE 2
+
 struct bgp_conn {
   struct bgp_proto *bgp;
   struct birdsock *sk;
index e591f89b2a10fd108bad16932c6e53d3ba0160a0..75b93391cf482a5c9ec83abbd7524b901ac62e75 100644 (file)
@@ -16,15 +16,16 @@ CF_DEFINES
 
 CF_DECLS
 
-CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
-       MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT, PATH, METRIC,
-       ERROR, START, DELAY, FORGET, WAIT, ENABLE, DISABLE, AFTER,
-       BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
-       BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
-       PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
-       CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER, MISSING, LLADDR,
-       DROP, IGNORE, ROUTE, REFRESH, INTERPRET, COMMUNITIES,
-       BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE)
+CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
+       KEEPALIVE, MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT,
+       PATH, METRIC, ERROR, START, DELAY, FORGET, WAIT, ENABLE,
+       DISABLE, AFTER, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN,
+       BGP_NEXT_HOP, BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY,
+       SOURCE, ADDRESS, PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4,
+       ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER,
+       MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH, INTERPRET,
+       COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE,
+       GATEWAY, DIRECT, RECURSIVE)
 
 CF_GRAMMAR
 
@@ -74,6 +75,8 @@ bgp_proto:
  | 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; }
+ | bgp_proto GATEWAY DIRECT ';' { BGP_CFG->gw_mode = GW_DIRECT; }
+ | bgp_proto GATEWAY RECURSIVE ';' { BGP_CFG->gw_mode = GW_RECURSIVE; }
  | bgp_proto PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; }
  | bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
  | bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; }
index ee2c1b0551bc84632872f954379f6b44cdc59aeb..6e230226ff93f03f2b67582b0f34012f9a43991b 100644 (file)
@@ -807,8 +807,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
   struct eattr *nh = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
   ip_addr nexthop = *(ip_addr *) nh->u.ptr->data;
 
-  if (!p->is_internal) /* FIXME better option
- */
+  if (p->cf->gw_mode == GW_DIRECT)
     {
       neighbor *ng = neigh_find(&p->p, &nexthop, 0) ? : p->neigh;
       if (ng->scope == SCOPE_HOST)
@@ -819,7 +818,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
       a->iface = ng->iface;
       a->hostentry = NULL;
     }
-  else
+  else /* GW_RECURSIVE */
     rta_set_recursive_next_hop(p->p.table, a, p->igp_table, &nexthop);
 
   return 1;