]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Minor cleanups
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 7 Feb 2017 14:55:51 +0000 (15:55 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 7 Feb 2017 14:55:51 +0000 (15:55 +0100)
doc/bird.sgml
proto/bgp/attrs.c
proto/bgp/bgp.h
proto/bgp/packets.c

index ff2c188f713b339b180e1908bcef4346fff59271..3ab9dee959e30f8246fdddc5f0f740ba7828e953 100644 (file)
@@ -2040,6 +2040,16 @@ using the following configuration parameters:
        source address for the BGP session. Default: the address of the local
        end of the interface our neighbor is connected to.
 
+       <tag><label id="bgp-strict-bind">strict bind <m/switch/</tag>
+       Specify whether BGP listening socket should be bound to a specific local
+       address (the same as the <cf/source address/) and associated interface,
+       or to all addresses. Binding to a specific address could be useful in
+       cases like running multiple BIRD instances on a machine, each using its
+       IP address. Note that listening sockets bound to a specific address and
+       to all addresses collide, therefore either all BGP protocols (of the
+       same address family and using the same local port) should have set
+       <cf/strict bind/, or none of them. Default: disabled.
+
        <tag><label id="bgp-next-hop-self">next hop self</tag>
        Avoid calculation of the Next Hop attribute and always advertise our own
        source address as a next hop. This needs to be used only occasionally to
@@ -2112,7 +2122,7 @@ using the following configuration parameters:
        Note that full (ICMP protection, for example) <rfc id="5082"> support is
        provided by Linux only. Default: disabled.
 
-       <tag><label id="bgp-pass">password <m/string/</tag>
+       <tag><label id="bgp-password">password <m/string/</tag>
        Use this password for MD5 authentication of BGP sessions (<rfc id="2385">). When
        used on BSD systems, see also <cf/setkey/ option below. Default: no
        authentication.
@@ -2270,13 +2280,6 @@ using the following configuration parameters:
        This option is relevant to IPv4 mode with enabled capability
        advertisement only. Default: on.
 
-       <tag><label id="bgp-route-limit">route limit <m/number/</tag>
-       The maximal number of routes that may be imported from the protocol. If
-       the route limit is exceeded, the connection is closed with an error.
-       Limit is currently implemented as <cf>import limit <m/number/ action
-       restart</cf>. This option is obsolete and it is replaced by
-       <ref id="proto-import-limit" name="import limit option">. Default: no limit.
-
        <tag><label id="bgp-disable-after-error">disable after error <m/switch/</tag>
        When an error is encountered (either locally or by the other side),
        disable the instance automatically and wait for an administrator to fix
index c557403b39f86dd21f51c42f920aef8dbb2676c7..d5bf2add9847875775f3e4ba2a0f5e9b20c6cf8f 100644 (file)
@@ -1325,29 +1325,23 @@ bgp_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct li
 
 static adata null_adata;       /* adata of length 0 */
 
-static inline void
-bgp_cluster_list_prepend(ea_list **attrs, struct linpool *pool, u32 id)
-{
-  eattr *a = bgp_find_attr(*attrs, BA_CLUSTER_LIST);
-  adata *d = int_set_add(pool, a ? a->u.ptr : NULL, id);
-  bgp_set_attr_ptr(attrs, pool, BA_CLUSTER_LIST, 0, d);
-}
-
 static ea_list *
-bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs, struct linpool *pool)
+bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs0, struct linpool *pool)
 {
   struct proto *SRC = e->attrs->src->proto;
   struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL;
   struct bgp_export_state s = { .proto = p, .channel =c, .pool = pool, .src = src, .route = e };
+  ea_list *attrs = attrs0;
   eattr *a;
+  adata *ad;
 
   /* ORIGIN attribute - mandatory, attach if missing */
-  if (! bgp_find_attr(attrs, BA_ORIGIN))
+  if (! bgp_find_attr(attrs0, BA_ORIGIN))
     bgp_set_attr_u32(&attrs, pool, BA_ORIGIN, 0, src ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
 
-  /* AS_PATH attribute */
-  a = bgp_find_attr(attrs, BA_AS_PATH);
-  adata *ad = a ? a->u.ptr : &null_adata;
+  /* AS_PATH attribute - mandatory */
+  a = bgp_find_attr(attrs0, BA_AS_PATH);
+  ad = a ? a->u.ptr : &null_adata;
 
   /* AS_PATH attribute - strip AS_CONFED* segments outside confederation */
   if ((!p->cf->confederation || !p->is_interior) && as_path_contains_confed(ad))
@@ -1374,33 +1368,40 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
     bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad);
 
     /* MULTI_EXIT_DESC attribute - accept only if set in export filter */
-    a = bgp_find_attr(attrs, BA_MULTI_EXIT_DISC);
+    a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC);
     if (a && !(a->type & EAF_FRESH))
       bgp_unset_attr(&attrs, pool, BA_MULTI_EXIT_DISC);
   }
 
   /* NEXT_HOP attribute - delegated to AF-specific hook */
-  a = bgp_find_attr(attrs, BA_NEXT_HOP);
+  a = bgp_find_attr(attrs0, BA_NEXT_HOP);
   bgp_update_next_hop(&s, a, &attrs);
 
   /* LOCAL_PREF attribute - required for IBGP, attach if missing */
-  if (p->is_interior && ! bgp_find_attr(attrs, BA_LOCAL_PREF))
+  if (p->is_interior && ! bgp_find_attr(attrs0, BA_LOCAL_PREF))
     bgp_set_attr_u32(&attrs, pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
 
   /* IBGP route reflection, RFC 4456 */
   if (src && src->is_internal && p->is_internal && (src->local_as == p->local_as))
   {
     /* ORIGINATOR_ID attribute - attach if not already set */
-    if (! bgp_find_attr(attrs, BA_ORIGINATOR_ID))
+    if (! bgp_find_attr(attrs0, BA_ORIGINATOR_ID))
       bgp_set_attr_u32(&attrs, pool, BA_ORIGINATOR_ID, 0, src->remote_id);
 
     /* CLUSTER_LIST attribute - prepend cluster ID */
+    a = bgp_find_attr(attrs0, BA_CLUSTER_LIST);
+    ad = a ? a->u.ptr : NULL;
+
+    /* Prepend src cluster ID */
     if (src->rr_cluster_id)
-      bgp_cluster_list_prepend(&attrs, pool, src->rr_cluster_id);
+      ad = int_set_add(pool, ad, src->rr_cluster_id);
 
-    /* Handle different src and dst cluster ID - prepend both ones */
+    /* Prepend dst cluster ID if src and dst clusters are different */
     if (p->rr_cluster_id && (src->rr_cluster_id != p->rr_cluster_id))
-      bgp_cluster_list_prepend(&attrs, pool, p->rr_cluster_id);
+      ad = int_set_add(pool, ad, p->rr_cluster_id);
+
+    /* Should be at least one prepended cluster ID */
+    bgp_set_attr_ptr(&attrs, pool, BA_CLUSTER_LIST, 0, ad);
   }
 
   /* AS4_* transition attributes, RFC 6793 4.2.2 */
@@ -1421,6 +1422,12 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
     }
   }
 
+  /*
+   * Presence of mandatory attributes ORIGIN and AS_PATH is ensured by above
+   * conditions. Presence and validity of quasi-mandatory NEXT_HOP attribute
+   * should be checked in AF-specific hooks.
+   */
+
   /* Apply per-attribute export hooks for validatation and normalization */
   return bgp_export_attrs(&s, attrs);
 }
index e5d860755c1f9b52a7e6b099affaaf32b2e98ab0..7d7d349a6cd96adb1e9a9b4edfca1c0c5bf770b1 100644 (file)
@@ -73,7 +73,7 @@ struct bgp_config {
   u16 local_port;                      /* Local listening port */
   u16 remote_port;                     /* Neighbor destination port */
   int multihop;                                /* Number of hops if multihop */
-  int strict_bind;                     /* Bind listening socket to local address XXXX */
+  int strict_bind;                     /* Bind listening socket to local address */
   int ttl_security;                    /* Enable TTL security [RFC 5082] */
   int compare_path_lengths;            /* Use path lengths when selecting best route */
   int med_metric;                      /* Compare MULTI_EXIT_DISC even between routes from differen ASes */
@@ -509,22 +509,18 @@ void bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to);
 #define BAF_PARTIAL            0x20
 #define BAF_EXT_LEN            0x10
 
-#define BA_ORIGIN              0x01    /* [RFC1771] */         /* WM */
+#define BA_ORIGIN              0x01    /* RFC 4271 */          /* WM */
 #define BA_AS_PATH             0x02                            /* WM */
 #define BA_NEXT_HOP            0x03                            /* WM */
 #define BA_MULTI_EXIT_DISC     0x04                            /* ON */
 #define BA_LOCAL_PREF          0x05                            /* WD */
 #define BA_ATOMIC_AGGR         0x06                            /* WD */
 #define BA_AGGREGATOR          0x07                            /* OT */
-#define BA_COMMUNITY           0x08    /* [RFC1997] */         /* OT */
-#define BA_ORIGINATOR_ID       0x09    /* [RFC1966] */         /* ON */
-#define BA_CLUSTER_LIST                0x0a                            /* ON */
-/* We don't support these: */
-#define BA_DPA                 0x0b    /* ??? */
-#define BA_ADVERTISER          0x0c    /* [RFC1863] */
-#define BA_RCID_PATH           0x0d
-#define BA_MP_REACH_NLRI       0x0e    /* [RFC2283] */
-#define BA_MP_UNREACH_NLRI     0x0f
+#define BA_COMMUNITY           0x08    /* RFC 1997 */          /* OT */
+#define BA_ORIGINATOR_ID       0x09    /* RFC 4456 */          /* ON */
+#define BA_CLUSTER_LIST                0x0a    /* RFC 4456 */          /* ON */
+#define BA_MP_REACH_NLRI       0x0e    /* RFC 4760 */
+#define BA_MP_UNREACH_NLRI     0x0f    /* RFC 4760 */
 #define BA_EXT_COMMUNITY       0x10    /* RFC 4360 */
 #define BA_AS4_PATH             0x11   /* RFC 6793 */
 #define BA_AS4_AGGREGATOR       0x12   /* RFC 6793 */
index dbc5fe12b2651ac727b1746be06c424529ed5194..385d5a3602207bff24deb2666686f02aa2d96b2a 100644 (file)
@@ -713,9 +713,13 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
 #define REPORT(msg, args...) \
   ({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
 
+#define DISCARD(msg, args...) \
+  ({ REPORT(msg, ## args); return; })
+
 #define WITHDRAW(msg, args...) \
   ({ REPORT(msg, ## args); s->err_withdraw = 1; return; })
 
+#define BAD_AFI                "Unexpected AF <%u/%u> in UPDATE"
 #define BAD_NEXT_HOP   "Invalid NEXT_HOP attribute"
 #define NO_NEXT_HOP    "Missing NEXT_HOP attribute"
 
@@ -836,21 +840,27 @@ bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
 static uint
 bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED)
 {
-  // FIXME
   return 0;
 }
 
 static void
 bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, rta *a UNUSED)
 {
-  // FIXME
+  /*
+   * Although we expect no next hop and RFC 7606 7.11 states that attribute
+   * MP_REACH_NLRI with unexpected next hop length is considered malformed,
+   * FlowSpec RFC 5575 4 states that next hop shall be ignored on receipt.
+   */
+
   return;
 }
 
 static void
-bgp_update_next_hop_none(struct bgp_export_state *s UNUSED, eattr *a UNUSED, ea_list **to UNUSED)
+bgp_update_next_hop_none(struct bgp_export_state *s, eattr *a, ea_list **to)
 {
-  // FIXME
+  /* NEXT_HOP shall not pass */
+  if (a)
+    bgp_unset_attr(to, s->pool, BA_NEXT_HOP);
 }
 
 
@@ -1652,15 +1662,15 @@ bgp_create_end_mark(struct bgp_channel *c, byte *buf)
 }
 
 static inline void
-bgp_rx_end_mark(struct bgp_proto *p, u32 afi)
+bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
 {
+  struct bgp_proto *p = s->proto;
   struct bgp_channel *c = bgp_get_channel(p, afi);
 
   BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
 
-  /* XXXX handle unknown AF in MP_*_NLRI */
   if (!c)
-    return;
+    DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
 
   if (c->load_state == BFS_LOADING)
     c->load_state = BFS_NONE;
@@ -1678,9 +1688,8 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis
   struct bgp_channel *c = bgp_get_channel(s->proto, afi);
   rta *a = NULL;
 
-  /* XXXX handle unknown AF in MP_*_NLRI */
   if (!c)
-    return;
+    DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
 
   s->channel = c;
   s->add_path = c->add_path_rx;
@@ -1791,12 +1800,12 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
 
   /* Check for End-of-RIB marker */
   if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
-  { bgp_rx_end_mark(p, BGP_AF_IPV4); goto done; }
+  { bgp_rx_end_mark(&s, BGP_AF_IPV4); goto done; }
 
   /* Check for MP End-of-RIB marker */
   if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
-      !s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af) /* XXXX  See RFC 7606 5.2 */
-  { bgp_rx_end_mark(p, s.mp_unreach_af); goto done; }
+      !s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af)
+  { bgp_rx_end_mark(&s, s.mp_unreach_af); goto done; }
 
   if (s.ip_unreach_len)
     bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);