]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: add cli command to control explicit-null label usage
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 17 Mar 2023 13:46:13 +0000 (14:46 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 11 Apr 2023 14:08:09 +0000 (16:08 +0200)
In BGP labeled unicast address-family, it is not possible to
send explicit-null label values with redistributed or network
declared prefixes.
A new CLI command is introduced:

  > [no] bgp labeled-unicast explicit-null

When used, the explicit-null value for IPv4 ('0' value) or
IPv6 ('2' value) will be used.
It is necessary to reconfigure the networks or the
redistribution in order to inherit this new behaviour.

Add the documentation.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_route.c
bgpd/bgp_vty.c
bgpd/bgpd.h
doc/user/bgp.rst

index a23bffd4ae960c944686ef4e2f8b6e96b0047e7d..b49206adceb5191b344b9dfd7ba74274a2844f21 100644 (file)
@@ -3070,7 +3070,9 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
  * the IMPLICIT_NULL label. This is pretty specialized: it's only called
  * in a path where we basically _know_ this is a BGP-LU route.
  */
-static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
+static bool bgp_lu_need_null_label(struct bgp *bgp,
+                                  const struct bgp_path_info *new_select,
+                                  afi_t afi, mpls_label_t *label)
 {
        /* Certain types get imp null; so do paths where the nexthop is
         * not labeled.
@@ -3079,12 +3081,20 @@ static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
            || new_select->sub_type == BGP_ROUTE_AGGREGATE
            || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
                return true;
-       else if (new_select->extra == NULL ||
-                !bgp_is_valid_label(&new_select->extra->label[0]))
-               /* TODO -- should be configurable? */
+       else if (new_select->extra &&
+                bgp_is_valid_label(&new_select->extra->label[0]))
+               return false;
+       if (label == NULL)
                return true;
+       if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
+               /* Disable PHP : explicit-null */
+               *label = afi == AFI_IP ? MPLS_LABEL_IPV4_EXPLICIT_NULL
+                                      : MPLS_LABEL_IPV6_EXPLICIT_NULL;
        else
-               return false;
+               /* Enforced PHP popping: implicit-null */
+               *label = MPLS_LABEL_IMPLICIT_NULL;
+
+       return true;
 }
 
 /*
@@ -3113,6 +3123,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
        struct bgp_path_info *old_select;
        struct bgp_path_info_pair old_and_new;
        int debug = 0;
+       mpls_label_t mpls_label_null;
 
        if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
                if (dest)
@@ -3167,7 +3178,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
         * Right now, since we only deal with per-prefix labels, it is not
         * necessary to do this upon changes to best path. Exceptions:
         * - label index has changed -> recalculate resulting label
-        * - path_info sub_type changed -> switch to/from implicit-null
+        * - path_info sub_type changed -> switch to/from null label value
         * - no valid label (due to removed static label binding) -> get new one
         */
        if (bgp->allocate_mpls_labels[afi][safi]) {
@@ -3176,11 +3187,12 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
                            || bgp_label_index_differs(new_select, old_select)
                            || new_select->sub_type != old_select->sub_type
                            || !bgp_is_valid_label(&dest->local_label)) {
-                               /* Enforced penultimate hop popping:
-                                * implicit-null for local routes, aggregate
-                                * and redistributed routes
+                               /* control label imposition for local routes,
+                                * aggregate and redistributed routes
                                 */
-                               if (bgp_lu_need_imp_null(new_select)) {
+                               mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
+                               if (bgp_lu_need_null_label(bgp, new_select, afi,
+                                                          &mpls_label_null)) {
                                        if (CHECK_FLAG(
                                                    dest->flags,
                                                    BGP_NODE_REGISTERED_FOR_LABEL)
@@ -3189,8 +3201,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
                                                    BGP_NODE_LABEL_REQUESTED))
                                                bgp_unregister_for_label(dest);
                                        dest->local_label = mpls_lse_encode(
-                                               MPLS_LABEL_IMPLICIT_NULL, 0, 0,
-                                               1);
+                                               mpls_label_null, 0, 0, 1);
                                        bgp_set_valid_label(&dest->local_label);
                                } else
                                        bgp_register_for_label(dest,
index f7b0caf493b148048f91d5ab4d6e243f83aaade5..de781d6b1e72bc009308f69e0559b05050314d0f 100644 (file)
@@ -2820,6 +2820,21 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd,
        return CMD_SUCCESS;
 }
 
+DEFPY(bgp_lu_uses_explicit_null, bgp_lu_uses_explicit_null_cmd,
+      "[no] bgp labeled-unicast explicit-null",
+      NO_STR BGP_STR
+      "BGP Labeled-unicast options\n"
+      "Use explicit-null label values for local prefixes\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+       if (no)
+               UNSET_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL);
+       else
+               SET_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL);
+       return CMD_SUCCESS;
+}
+
 DEFUN(bgp_suppress_duplicates, bgp_suppress_duplicates_cmd,
       "bgp suppress-duplicates",
       BGP_STR
@@ -18235,6 +18250,9 @@ int bgp_config_write(struct vty *vty)
                                        ? ""
                                        : "no ");
 
+               if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
+                       vty_out(vty, " bgp labeled-unicast explicit-null\n");
+
                /* draft-ietf-idr-deprecate-as-set-confed-set */
                if (bgp->reject_as_sets)
                        vty_out(vty, " bgp reject-as-sets\n");
@@ -19154,6 +19172,9 @@ void bgp_vty_init(void)
        install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd);
        install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd);
 
+       /* bgp labeled-unicast explicit-null */
+       install_element(BGP_NODE, &bgp_lu_uses_explicit_null_cmd);
+
        /* bgp suppress-duplicates */
        install_element(BGP_NODE, &bgp_suppress_duplicates_cmd);
        install_element(BGP_NODE, &no_bgp_suppress_duplicates_cmd);
index a08a2870ee7ce54fa1342e57ceb75a8c24c04715..b6491bf7995381c670ddd8c39935ff1d422a4c22 100644 (file)
@@ -500,6 +500,8 @@ struct bgp {
 #define BGP_FLAG_HARD_ADMIN_RESET (1ULL << 31)
 /* Evaluate the AIGP attribute during the best path selection process */
 #define BGP_FLAG_COMPARE_AIGP (1ULL << 32)
+/* For BGP-LU, force local prefixes to use explicit-null label */
+#define BGP_FLAG_LU_EXPLICIT_NULL (1ULL << 33)
 
        /* BGP default address-families.
         * New peers inherit enabled afi/safis from bgp instance.
index 946f0699f271cfcb55e585d067dcc94d68537048..97d7ce6b7571c5496583e072da3c7650f8060ae3 100644 (file)
@@ -2767,6 +2767,17 @@ happened automatically if local-role is set.
    value of his role (by setting local-role on his side). Otherwise, a Role
    Mismatch Notification will be sent.
 
+Labeled unicast
+---------------
+
+*bgpd* supports labeled information, as per :rfc:`3107`.
+
+.. clicmd:: bgp labeled-unicast explicit-null
+
+By default, locally advertised prefixes use the `implicit-null` label to
+encode in the outgoing NLRI. The following command uses the `explicit-null`
+label value for all the BGP instances.
+
 .. _bgp-l3vpn-vrfs:
 
 L3VPN VRFs