]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Add MPLS support
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 15 Sep 2022 00:30:15 +0000 (02:30 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 4 Oct 2023 11:01:21 +0000 (13:01 +0200)
When MPLS is active, received routes on MPLS-aware SAFIs (ipvX-mpls,
vpnX-mpls) are automatically labeled according to active label policy and
corresponding MPLS routes are automatically generated. Also routes sent
on MPLS-aware SAFIs announce local labels when it should be done.

proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/config.Y
proto/bgp/packets.c

index de45cae0e6181d90829f51e423c614795e6bb5c4..9387ddba97f99bd928abdc4f2f57674a9def02e7 100644 (file)
@@ -17,6 +17,7 @@
 #include "nest/protocol.h"
 #include "nest/route.h"
 #include "nest/attrs.h"
+#include "nest/mpls.h"
 #include "conf/conf.h"
 #include "lib/resource.h"
 #include "lib/string.h"
@@ -1501,6 +1502,13 @@ bgp_finish_attrs(struct bgp_parse_state *s, rta *a)
               p->cf->local_role == BGP_ROLE_RS_CLIENT))
       bgp_set_attr_u32(&a->eattrs, s->pool, BA_ONLY_TO_CUSTOMER, 0, p->cf->remote_as);
   }
+
+  /* Apply MPLS policy for labeled SAFIs */
+  if (s->mpls && s->proto->p.mpls_channel)
+  {
+    struct mpls_channel *mc = (void *) s->proto->p.mpls_channel;
+    ea_set_attr_u32(&a->eattrs, s->pool, EA_MPLS_POLICY, 0, EAF_TYPE_INT, mc->label_policy);
+  }
 }
 
 
index f668b3717fda4a2f61b36773c0596cc710d5d531..4651b76a2f84bfb319aab98d23b7c9fb6485103c 100644 (file)
@@ -522,6 +522,8 @@ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
 void
 bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len)
 {
+  proto_shutdown_mpls_map(&p->p, 1);
+
   proto_notify_state(&p->p, PS_STOP);
   bgp_graceful_close_conn(&p->outgoing_conn, subcode, data, len);
   bgp_graceful_close_conn(&p->incoming_conn, subcode, data, len);
@@ -1573,6 +1575,8 @@ bgp_start(struct proto *P)
   p->remote_id = 0;
   p->link_addr = IPA_NONE;
 
+  proto_setup_mpls_map(P, RTS_BGP, 1);
+
   /* Lock all channels when in GR recovery mode */
   if (p->p.gr_recovery && p->cf->gr_mode)
   {
@@ -1729,11 +1733,14 @@ bgp_init(struct proto_config *CF)
   if (cf->c.parent)
     cf->remote_ip = IPA_NONE;
 
-  /* Add all channels */
+  /* Add all BGP channels */
   struct bgp_channel_config *cc;
   BGP_CF_WALK_CHANNELS(cf, cc)
     proto_add_channel(P, &cc->c);
 
+  /* Add MPLS channel */
+  proto_configure_channel(P, &P->mpls_channel, proto_cf_mpls_channel(CF));
+
   return P;
 }
 
@@ -2153,16 +2160,23 @@ bgp_reconfigure(struct proto *P, struct proto_config *CF)
   WALK_LIST(C, p->p.channels)
     C->stale = 1;
 
+  /* Reconfigure BGP channels */
   BGP_CF_WALK_CHANNELS(new, cc)
   {
     C = (struct channel *) bgp_find_channel(p, cc->afi);
     same = proto_configure_channel(P, &C, &cc->c) && same;
   }
 
+  /* Reconfigure MPLS channel */
+  same = proto_configure_channel(P, &P->mpls_channel, proto_cf_mpls_channel(CF)) && same;
+
   WALK_LIST_DELSAFE(C, C2, p->p.channels)
     if (C->stale)
       same = proto_configure_channel(P, &C, NULL) && same;
 
+  if (same)
+    proto_setup_mpls_map(P, RTS_BGP, 1);
+
   if (same && (p->start_state > BSS_PREPARE))
     bgp_update_bfd(p, new->bfd);
 
@@ -2653,7 +2667,7 @@ struct protocol proto_bgp = {
   .template =          "bgp%d",
   .class =             PROTOCOL_BGP,
   .preference =        DEF_PREF_BGP,
-  .channel_mask =      NB_IP | NB_VPN | NB_FLOW,
+  .channel_mask =      NB_IP | NB_VPN | NB_FLOW | NB_MPLS,
   .proto_size =                sizeof(struct bgp_proto),
   .config_size =       sizeof(struct bgp_config),
   .postconfig =                bgp_postconfig,
index f589fd8402542fba556fc1caec6f2eb9192acf4b..e7a2f5cb0630bfb08eaa2dcaefabb2dc1dda0147 100644 (file)
@@ -129,6 +129,7 @@ bgp_proto:
    bgp_proto_start proto_name '{'
  | bgp_proto proto_item ';'
  | bgp_proto bgp_proto_channel ';'
+ | bgp_proto mpls_channel ';'
  | bgp_proto LOCAL bgp_loc_opts ';'
  | bgp_proto LOCAL ipa ipa_scope bgp_loc_opts ';' {
      BGP_CFG->local_ip = $3;
index 054e6c3c14a4f343f810dd535585fbae8578c88b..b7df5a7adf0fc1fb4b0481d9419fe3c5886d636e 100644 (file)
@@ -1217,11 +1217,10 @@ bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
       bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, ipa_nonzero(nh[1]) ? 32 : 16);
       s->local_next_hop = 1;
 
-      /* TODO: Use local MPLS assigned label */
       if (s->mpls)
       {
-       u32 implicit_null = BGP_MPLS_NULL;
-       bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, &implicit_null, 4);
+       u32 label = ea_get_int(s->route->attrs->eattrs, EA_MPLS_LABEL, BGP_MPLS_NULL);
+       bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, &label, 4);
       }
       else
        bgp_unset_attr(to, s->pool, BA_MPLS_LABEL_STACK);