]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit '971721c9' into thread-next
authorMaria Matejka <mq@ucw.cz>
Fri, 5 Aug 2022 08:26:13 +0000 (10:26 +0200)
committerMaria Matejka <mq@ucw.cz>
Fri, 5 Aug 2022 08:26:13 +0000 (10:26 +0200)
1  2 
doc/bird.sgml
proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/config.Y
proto/bgp/packets.c

diff --cc doc/bird.sgml
Simple merge
index a1f5791a6ed3197cdd0ad4d3638f98587030d47f,0d2116b7859150abf8e0bfc157e4665391a35154..91487faed0925fdccaeb8e09bc700b5fc20b2ba4
@@@ -936,9 -893,21 +936,21 @@@ bgp_decode_large_community(struct bgp_p
  
    struct adata *ad = lp_alloc_adata(s->pool, len);
    get_u32s(data, (u32 *) ad->data, len / 4);
 -  bgp_set_attr_ptr(to, s->pool, BA_LARGE_COMMUNITY, flags, ad);
 +  bgp_set_attr_ptr(to, BA_LARGE_COMMUNITY, flags, ad);
  }
  
 -  bgp_set_attr_u32(to, s->pool, BA_ONLY_TO_CUSTOMER, flags, val);
+ static void
+ bgp_decode_otc(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data UNUSED, uint len, ea_list **to)
+ {
+   if (len != 4)
+     WITHDRAW(BAD_LENGTH, "OTC", len);
+   u32 val = get_u32(data);
++  bgp_set_attr_u32(to, BA_ONLY_TO_CUSTOMER, flags, val);
+ }
  static void
  bgp_export_mpls_label_stack(struct bgp_export_state *s, eattr *a)
  {
@@@ -1175,10 -1121,16 +1187,17 @@@ static union bgp_attr_desc bgp_attr_tab
      .encode = bgp_encode_u32s,
      .decode = bgp_decode_large_community,
    },
 -    .type = EAF_TYPE_INT,
+   [BA_ONLY_TO_CUSTOMER] = {
+     .name = "otc",
++    .type = T_INT,
+     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
+     .encode = bgp_encode_u32,
+     .decode = bgp_decode_otc,
+   },
    [BA_MPLS_LABEL_STACK] = {
 -    .name = "mpls_label_stack",
 -    .type = EAF_TYPE_INT_SET,
 +    .name = "bgp_mpls_label_stack",
 +    .type = T_CLIST,
 +    .readonly = 1,
      .export = bgp_export_mpls_label_stack,
      .encode = bgp_encode_mpls_label_stack,
      .decode = bgp_decode_mpls_label_stack,
@@@ -1502,8 -1462,31 +1521,31 @@@ bgp_finish_attrs(struct bgp_parse_stat
    if (BIT32_TEST(s->attrs_seen, BA_AIGP) && !s->channel->cf->aigp)
    {
      REPORT("Discarding AIGP attribute received on non-AIGP session");
 -    bgp_unset_attr(&a->eattrs, s->pool, BA_AIGP);
 +    bgp_unset_attr(to, BA_AIGP);
    }
 -    eattr *e = bgp_find_attr(a->eattrs, BA_ONLY_TO_CUSTOMER);
+   /* Handle OTC ingress procedure, RFC 9234 */
+   if (bgp_channel_is_role_applicable(s->channel))
+   {
+     struct bgp_proto *p = s->proto;
 -      bgp_set_attr_u32(&a->eattrs, s->pool, BA_ONLY_TO_CUSTOMER, 0, p->cf->remote_as);
++    eattr *e = bgp_find_attr(*to, BA_ONLY_TO_CUSTOMER);
+     /* Reject routes from downstream if they are leaked */
+     if (e && (p->cf->local_role == BGP_ROLE_PROVIDER ||
+             p->cf->local_role == BGP_ROLE_RS_SERVER))
+       WITHDRAW("Route leak detected - OTC attribute from downstream");
+     /* Reject routes from peers if they are leaked */
+     if (e && (p->cf->local_role == BGP_ROLE_PEER) && (e->u.data != p->cf->remote_as))
+       WITHDRAW("Route leak detected - OTC attribute with mismatched ASN (%u)",
+              (uint) e->u.data);
+     /* Mark routes from upstream if it did not happened before */
+     if (!e && (p->cf->local_role == BGP_ROLE_CUSTOMER ||
+              p->cf->local_role == BGP_ROLE_PEER ||
+              p->cf->local_role == BGP_ROLE_RS_CLIENT))
++      bgp_set_attr_u32(to, BA_ONLY_TO_CUSTOMER, 0, p->cf->remote_as);
+   }
  }
  
  
@@@ -1957,10 -1711,13 +1999,11 @@@ bgp_setup_out_table(struct bgp_channel 
   */
  
  int
 -bgp_preexport(struct channel *C, rte **new, struct linpool *pool UNUSED)
 +bgp_preexport(struct channel *C, rte *e)
  {
 -  rte *e = *new;
 -  struct proto *SRC = e->attrs->src->proto;
+   struct bgp_channel *c = (struct bgp_channel *) C;
    struct bgp_proto *p = (struct bgp_proto *) C->proto;
 -  struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL;
 +  struct bgp_proto *src = bgp_rte_proto(e);
  
    /* Reject our routes */
    if (src == p)
    }
  
    /* Handle well-known communities, RFC 1997 */
-   struct eattr *com;
+   struct eattr *a;
    if (p->cf->interpret_communities &&
-       (com = ea_find(e->attrs, BGP_EA_ID(BA_COMMUNITY))))
 -      (a = bgp_find_attr(e->attrs->eattrs, BA_COMMUNITY)))
++      (a = bgp_find_attr(e->attrs, BA_COMMUNITY)))
    {
-     const struct adata *d = com->u.ptr;
+     const struct adata *d = a->u.ptr;
  
      /* Do not export anywhere */
      if (int_set_contains(d, BGP_COMM_NO_ADVERTISE))
        return -1;
    }
  
 -    a = bgp_find_attr(e->attrs->eattrs, BA_ONLY_TO_CUSTOMER);
+   /* Do not export routes marked with OTC to upstream, RFC 9234 */
+   if (bgp_channel_is_role_applicable(c))
+   {
++    a = bgp_find_attr(e->attrs, BA_ONLY_TO_CUSTOMER);
+     if (a && (p->cf->local_role==BGP_ROLE_CUSTOMER ||
+             p->cf->local_role==BGP_ROLE_PEER ||
+             p->cf->local_role==BGP_ROLE_RS_CLIENT))
+       return -1;
+   }
    return 0;
  }
  
@@@ -2131,6 -1887,16 +2184,16 @@@ bgp_update_attrs(struct bgp_proto *p, s
      }
    }
  
 -      bgp_set_attr_u32(&attrs, pool, BA_ONLY_TO_CUSTOMER, 0, p->public_as);
+   /* Mark routes for downstream with OTC, RFC 9234 */
+   if (bgp_channel_is_role_applicable(c))
+   {
+     a = bgp_find_attr(attrs, BA_ONLY_TO_CUSTOMER);
+     if (!a && (p->cf->local_role == BGP_ROLE_PROVIDER ||
+              p->cf->local_role == BGP_ROLE_PEER ||
+              p->cf->local_role == BGP_ROLE_RS_SERVER))
++      bgp_set_attr_u32(&attrs, BA_ONLY_TO_CUSTOMER, 0, p->public_as);
+   }
    /*
     * Presence of mandatory attributes ORIGIN and AS_PATH is ensured by above
     * conditions. Presence and validity of quasi-mandatory NEXT_HOP attribute
diff --cc proto/bgp/bgp.c
Simple merge
diff --cc proto/bgp/bgp.h
index fdd134f4ffab7355eb6306eb2bf20702cbe20fa7,fea8730413ef0bfe5f26f1066a5409683742474f..0cd327a273149e85f2282d44fcff51d6c4764b28
@@@ -649,31 -659,27 +665,32 @@@ void bgp_update_next_hop(struct bgp_exp
  
  #define BAF_DECODE_FLAGS      0x0100  /* Private flag - attribute flags are handled by the decode hook */
  
 -#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    /* 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 */
 -#define BA_AIGP                       0x1a    /* RFC 7311 */
 -#define BA_LARGE_COMMUNITY    0x20    /* RFC 8092 */
 +enum bgp_attr_id {
 +  BA_ORIGIN           = 0x01, /* RFC 4271 */          /* WM */
 +  BA_AS_PATH          = 0x02,                         /* WM */
 +  BA_NEXT_HOP         = 0x03,                         /* WM */
 +  BA_MULTI_EXIT_DISC  = 0x04,                         /* ON */
 +  BA_LOCAL_PREF               = 0x05,                         /* WD */
 +  BA_ATOMIC_AGGR      = 0x06,                         /* WD */
 +  BA_AGGREGATOR               = 0x07,                         /* OT */
 +  BA_COMMUNITY                = 0x08, /* RFC 1997 */          /* OT */
 +  BA_ORIGINATOR_ID    = 0x09, /* RFC 4456 */          /* ON */
 +  BA_CLUSTER_LIST     = 0x0a, /* RFC 4456 */          /* ON */
 +  BA_MP_REACH_NLRI    = 0x0e, /* RFC 4760 */
 +  BA_MP_UNREACH_NLRI  = 0x0f, /* RFC 4760 */
 +  BA_EXT_COMMUNITY    = 0x10, /* RFC 4360 */
 +  BA_AS4_PATH         = 0x11, /* RFC 6793 */
 +  BA_AS4_AGGREGATOR   = 0x12, /* RFC 6793 */
 +  BA_AIGP             = 0x1a, /* RFC 7311 */
 +  BA_LARGE_COMMUNITY  = 0x20, /* RFC 8092 */
+ #define BA_ONLY_TO_CUSTOMER   0x23    /* RFC 9234 */
  
  /* Bird's private internal BGP attributes */
 -#define BA_MPLS_LABEL_STACK   0xfe    /* MPLS label stack transfer attribute */
 +  BA_MPLS_LABEL_STACK = 0x100, /* MPLS label stack transfer attribute */
 +
 +/* Maximum */
 +  BGP_ATTR_MAX,
 +};
  
  /* BGP connection states */
  
index 24f3ec8f412180757a030a25697e752c1c1b9581,cb410a5e85c266155d8b9f755b1a0882a34c8753..9f0d230660b70f7c89000ed59bc4f7acabaea43b
@@@ -29,8 -30,9 +29,9 @@@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, H
        GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
        STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
        LIVED, STALE, IMPORT, IBGP, EBGP, MANDATORY, INTERNAL, EXTERNAL, SETS,
 -      DYNAMIC, RANGE, NAME, DIGITS, BGP_AIGP, AIGP, ORIGINATE, COST, ENFORCE,
 +      DYNAMIC, RANGE, NAME, DIGITS, AIGP, ORIGINATE, COST, ENFORCE,
-       FIRST, FREE, VALIDATE, BASE)
+       FIRST, FREE, VALIDATE, BASE, ROLE, ROLES, PEER, PROVIDER, CUSTOMER,
+       RS_SERVER, RS_CLIENT, REQUIRE, BGP_OTC)
  
  %type <i> bgp_nh
  %type <i32> bgp_afi
Simple merge