]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #12728 from opensourcerouting/feature/bgp_neighbor_path-attribute_...
authorRuss White <russ@riw.us>
Tue, 14 Feb 2023 16:22:16 +0000 (11:22 -0500)
committerGitHub <noreply@github.com>
Tue, 14 Feb 2023 16:22:16 +0000 (11:22 -0500)
bgpd: Add neighbor path-attribute treat-as-withdraw command

1  2 
bgpd/bgp_vty.c
bgpd/bgpd.h
doc/user/bgp.rst

diff --combined bgpd/bgp_vty.c
index daa435bb2d5c8281ebc3345fafbaf08681456b40,0ba3c760c32c17ae388a338d172d9d3a59bd797c..27f0ea9b7191a9ad8e312912c30050368eb8a3f9
@@@ -178,14 -178,10 +178,14 @@@ static enum node_type bgp_node_type(afi
                        return BGP_VPNV4_NODE;
                case SAFI_FLOWSPEC:
                        return BGP_FLOWSPECV4_NODE;
 -              default:
 +              case SAFI_UNSPEC:
 +              case SAFI_ENCAP:
 +              case SAFI_EVPN:
 +              case SAFI_MAX:
                        /* not expected */
                        return BGP_IPV4_NODE;
                }
 +              break;
        case AFI_IP6:
                switch (safi) {
                case SAFI_UNICAST:
                        return BGP_VPNV6_NODE;
                case SAFI_FLOWSPEC:
                        return BGP_FLOWSPECV6_NODE;
 -              default:
 -                      /* not expected */
 +              case SAFI_UNSPEC:
 +              case SAFI_ENCAP:
 +              case SAFI_EVPN:
 +              case SAFI_MAX:
 +                      /* not expected and the return value seems wrong */
                        return BGP_IPV4_NODE;
                }
 +              break;
        case AFI_L2VPN:
                return BGP_EVPN_NODE;
        case AFI_UNSPEC:
@@@ -543,9 -535,7 +543,9 @@@ static const char *get_bgp_default_af_f
                        return "ipv4-labeled-unicast";
                case SAFI_FLOWSPEC:
                        return "ipv4-flowspec";
 -              default:
 +              case SAFI_UNSPEC:
 +              case SAFI_EVPN:
 +              case SAFI_MAX:
                        return "unknown-afi/safi";
                }
                break;
                        return "ipv6-labeled-unicast";
                case SAFI_FLOWSPEC:
                        return "ipv6-flowspec";
 -              default:
 +              case SAFI_UNSPEC:
 +              case SAFI_EVPN:
 +              case SAFI_MAX:
                        return "unknown-afi/safi";
                }
                break;
                switch (safi) {
                case SAFI_EVPN:
                        return "l2vpn-evpn";
 -              default:
 +              case SAFI_UNICAST:
 +              case SAFI_MULTICAST:
 +              case SAFI_MPLS_VPN:
 +              case SAFI_ENCAP:
 +              case SAFI_LABELED_UNICAST:
 +              case SAFI_FLOWSPEC:
 +              case SAFI_UNSPEC:
 +              case SAFI_MAX:
                        return "unknown-afi/safi";
                }
 +              break;
        case AFI_UNSPEC:
        case AFI_MAX:
                return "unknown-afi/safi";
        }
        /* all AFIs are accounted for above, so this shouldn't happen */
 -      return "unknown-afi/safi";
 +
 +      assert(!"Reached end of function where we did not expect to");
  }
  
  int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
@@@ -8840,6 -8819,59 +8840,59 @@@ DEFPY(no_neighbor_path_attribute_discar
        return CMD_SUCCESS;
  }
  
+ DEFPY(neighbor_path_attribute_treat_as_withdraw,
+       neighbor_path_attribute_treat_as_withdraw_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor path-attribute treat-as-withdraw (1-255)...",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Manipulate path attributes from incoming UPDATE messages\n"
+       "Treat-as-withdraw any incoming BGP UPDATE messages that contain the specified attribute\n"
+       "Attribute number\n")
+ {
+       struct peer *peer;
+       int idx = 0;
+       const char *withdraw_attrs = NULL;
+       peer = peer_and_group_lookup_vty(vty, neighbor);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+       argv_find(argv, argc, "(1-255)", &idx);
+       if (idx)
+               withdraw_attrs = argv_concat(argv, argc, idx);
+       bgp_path_attribute_withdraw_vty(vty, peer, withdraw_attrs, true);
+       return CMD_SUCCESS;
+ }
+ DEFPY(no_neighbor_path_attribute_treat_as_withdraw,
+       no_neighbor_path_attribute_treat_as_withdraw_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor path-attribute treat-as-withdraw (1-255)...",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Manipulate path attributes from incoming UPDATE messages\n"
+       "Treat-as-withdraw any incoming BGP UPDATE messages that contain the specified attribute\n"
+       "Attribute number\n")
+ {
+       struct peer *peer;
+       int idx = 0;
+       const char *withdraw_attrs = NULL;
+       peer = peer_and_group_lookup_vty(vty, neighbor);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+       argv_find(argv, argc, "(1-255)", &idx);
+       if (idx)
+               withdraw_attrs = argv_concat(argv, argc, idx);
+       bgp_path_attribute_withdraw_vty(vty, peer, withdraw_attrs, false);
+       return CMD_SUCCESS;
+ }
  static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
                         struct ecommunity **list, bool is_rt6)
  {
@@@ -17480,6 -17512,16 +17533,16 @@@ static void bgp_config_write_peer_globa
                vty_out(vty, " neighbor %s path-attribute discard %s\n", addr,
                        discard_attrs_str);
  
+       /* path-attribute treat-as-withdraw */
+       char withdraw_attrs_str[BUFSIZ] = {0};
+       bool withdraw_attrs = bgp_path_attribute_treat_as_withdraw(
+               peer, withdraw_attrs_str, sizeof(withdraw_attrs_str));
+       if (withdraw_attrs)
+               vty_out(vty,
+                       " neighbor %s path-attribute treat-as-withdraw %s\n",
+                       addr, withdraw_attrs_str);
        if (!CHECK_FLAG(peer->peer_gr_new_status_flag,
                        PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)) {
  
@@@ -19591,6 -19633,12 +19654,12 @@@ void bgp_vty_init(void
        install_element(BGP_NODE, &neighbor_path_attribute_discard_cmd);
        install_element(BGP_NODE, &no_neighbor_path_attribute_discard_cmd);
  
+       /* "neighbor path-attribute treat-as-withdraw" commands. */
+       install_element(BGP_NODE,
+                       &neighbor_path_attribute_treat_as_withdraw_cmd);
+       install_element(BGP_NODE,
+                       &no_neighbor_path_attribute_treat_as_withdraw_cmd);
        /* "neighbor passive" commands. */
        install_element(BGP_NODE, &neighbor_passive_cmd);
        install_element(BGP_NODE, &no_neighbor_passive_cmd);
diff --combined bgpd/bgpd.h
index 61119ab6e0b96370836ec386cff57630f968873c,8f7040dce6e85b4e4f09313d6cfbeb039878817d..64f016dfc5b7ce787749106ecd74775928a6dbfd
@@@ -1768,6 -1768,9 +1768,9 @@@ struct peer 
        /* Path attributes discard */
        bool discard_attrs[BGP_ATTR_MAX];
  
+       /* Path attributes treat-as-withdraw */
+       bool withdraw_attrs[BGP_ATTR_MAX];
        QOBJ_FIELDS;
  };
  DECLARE_QOBJ_TYPE(peer);
@@@ -2421,9 -2424,7 +2424,9 @@@ static inline int afindex(afi_t afi, sa
                        return BGP_AF_IPV4_ENCAP;
                case SAFI_FLOWSPEC:
                        return BGP_AF_IPV4_FLOWSPEC;
 -              default:
 +              case SAFI_EVPN:
 +              case SAFI_UNSPEC:
 +              case SAFI_MAX:
                        return BGP_AF_MAX;
                }
                break;
                        return BGP_AF_IPV6_ENCAP;
                case SAFI_FLOWSPEC:
                        return BGP_AF_IPV6_FLOWSPEC;
 -              default:
 +              case SAFI_EVPN:
 +              case SAFI_UNSPEC:
 +              case SAFI_MAX:
                        return BGP_AF_MAX;
                }
                break;
                switch (safi) {
                case SAFI_EVPN:
                        return BGP_AF_L2VPN_EVPN;
 -              default:
 +              case SAFI_UNICAST:
 +              case SAFI_MULTICAST:
 +              case SAFI_LABELED_UNICAST:
 +              case SAFI_MPLS_VPN:
 +              case SAFI_ENCAP:
 +              case SAFI_FLOWSPEC:
 +              case SAFI_UNSPEC:
 +              case SAFI_MAX:
                        return BGP_AF_MAX;
                }
 -      default:
 +              break;
 +      case AFI_UNSPEC:
 +      case AFI_MAX:
                return BGP_AF_MAX;
        }
 +
 +      assert(!"Reached end of function we should never hit");
  }
  
  /* If the peer is not a peer-group but is bound to a peer-group return 1 */
@@@ -2635,6 -2623,8 +2638,8 @@@ extern void peer_on_policy_change(struc
                                  int outbound);
  extern bool bgp_path_attribute_discard(struct peer *peer, char *buf,
                                       size_t size);
+ extern bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf,
+                                                size_t size);
  #ifdef _FRR_ATTRIBUTE_PRINTFRR
  /* clang-format off */
  #pragma FRR printfrr_ext "%pBP" (struct peer *)
diff --combined doc/user/bgp.rst
index b17442f64160c65747a68f1ac0499314d36003a0,8a840e0ef7bd19902a52b823e164d13c9c62c3b9..6979c77d736d782e17586ca9a507bdbeaa1182e6
@@@ -1711,6 -1711,11 +1711,11 @@@ Configuring Peer
     If you do not want specific attributes, you can drop them using this command, and
     let the BGP proceed by ignoring those attributes.
  
+ .. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> path-attribute treat-as-withdraw (1-255)...
+    Received BGP UPDATES that contain specified path attributes are treat-as-withdraw. If
+    there is an existing prefix in the BGP routing table, it will be removed.
  .. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> graceful-shutdown
  
     Mark all routes from this neighbor as less preferred by setting ``graceful-shutdown``
  Displaying Information about Peers
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  
 -.. clicmd:: show bgp <afi> <safi> neighbors WORD bestpath-routes [json] [wide]
 +.. clicmd:: show bgp <afi> <safi> neighbors WORD bestpath-routes [detail] [json] [wide]
  
     For the given neighbor, WORD, that is specified list the routes selected
     by BGP as having the best path.
  
 +   If ``detail`` option is specified, the detailed version of all routes
 +   will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
 +   will be used, but for the whole table of received, advertised or filtered
 +   prefixes.
 +
 +   If ``json`` option is specified, output is displayed in JSON format.
 +
 +   If ``wide`` option is specified, then the prefix table's width is increased
 +   to fully display the prefix and the nexthop.
 +
  .. _bgp-peer-filtering:
  
  Peer Filtering
@@@ -3926,7 -3921,7 +3931,7 @@@ structure is extended with :clicmd:`sho
     The ``terse`` option can be used in combination with the remote-as, neighbor,
     failed and established filters, and with the ``wide`` option as well.
  
 -.. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [detail] [json]
 +.. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [<A.B.C.D/M|X:X::X:X/M> | detail] [json]
  
     This command shows information on a specific BGP peer of the relevant
     afi and safi selected.
     The ``received-routes`` keyword displays all routes belonging to this
     address-family (prior to inbound policy) that were received by this peer.
  
 +   If a specific prefix is specified, the detailed version of that prefix will
 +   be displayed.
 +
     If ``detail`` option is specified, the detailed version of all routes
     will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
     will be used, but for the whole table of received, advertised or filtered
  
     If the ``json`` option is specified, output is displayed in JSON format.
  
 -.. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [detail] [json|wide]
 +.. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [<A.B.C.D/M|X:X::X:X/M> | detail] [json|wide]
  
     Display the routes advertised to a BGP neighbor or received routes
     from neighbor or filtered routes received from neighbor based on the
     if afi is specified, with ``all`` option, routes will be displayed for
     each SAFI in the selcted AFI
  
 +   If a specific prefix is specified, the detailed version of that prefix will
 +   be displayed.
 +
     If ``detail`` option is specified, the detailed version of all routes
     will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
     will be used, but for the whole table of received, advertised or filtered