]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: add [no]neighbor capability fqdn command
authorFrancois Dumontet <francois.dumontet@6wind.com>
Mon, 22 Jan 2024 10:53:36 +0000 (11:53 +0100)
committerFrancois Dumontet <francois.dumontet@6wind.com>
Fri, 2 Feb 2024 10:31:47 +0000 (11:31 +0100)
cisco routers are not dealing fairly whith unsupported capabilities.
When a cisco router receive an unsupported capabilities it reset the
negociation without notifying the unmatching capability as described in
RFC2842.
Cisco suggest the use of
neighbor x.x.x.x capability fqdn
to avoid the use of fqdn in open message.

this new command is to remove the use of fqdn capability in the
open message with the peer "x.x.x.x".

Link: https://www.cisco.com/c/en/us/support/docs/ip/border-gateway-protocol-bgp/116189-problemsolution-technology-00.pdf
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
bgpd/bgp_open.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h
tests/bgpd/test_peer_attr.c
tests/bgpd/test_peer_attr.py

index 154efdedaf3500e88f94ceb6461da2d0eb90216e..43a59e24489c43e621e2a737545eb379f39b1c6c 100644 (file)
@@ -1897,8 +1897,9 @@ uint16_t bgp_open_capability(struct stream *s, struct peer *peer,
                stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
        }
 
-       /* Hostname capability */
-       if (cmd_hostname_get()) {
+       /* FQDN capability */
+       if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_FQDN)
+           && cmd_hostname_get()) {
                SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
                stream_putc(s, BGP_OPEN_OPT_CAP);
                rcapp = stream_get_endp(s); /* Ptr to length placeholder */
index 2a917155362b98386c11686c0d76911b6c7f0362..09f9667a9a097f8485fcadef17db590e4b903d38 100644 (file)
@@ -5735,6 +5735,30 @@ DEFUN (no_neighbor_dont_capability_negotiate,
                                   PEER_FLAG_DONT_CAPABILITY);
 }
 
+/* neighbor capability fqdn */
+DEFPY (neighbor_capability_fqdn,
+       neighbor_capability_fqdn_cmd,
+       "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor capability fqdn",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Advertise capability to the peer\n"
+       "Advertise fqdn capability to the peer\n")
+{
+       struct peer *peer;
+
+       peer = peer_and_group_lookup_vty(vty, neighbor);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       if (no)
+               return peer_flag_unset_vty(vty, neighbor,
+                                         PEER_FLAG_CAPABILITY_FQDN);
+       else
+               return peer_flag_set_vty(vty, neighbor,
+                                       PEER_FLAG_CAPABILITY_FQDN);
+}
+
 /* neighbor capability extended next hop encoding */
 DEFUN (neighbor_capability_enhe,
        neighbor_capability_enhe_cmd,
@@ -18189,6 +18213,12 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
        if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY))
                vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr);
 
+       /* capability fqdn */
+       if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_FQDN))
+               vty_out(vty,
+                       " no neighbor %s capability fqdn\n",
+                       addr);
+
        /* override-capability */
        if (peergroup_flag_check(peer, PEER_FLAG_OVERRIDE_CAPABILITY))
                vty_out(vty, " neighbor %s override-capability\n", addr);
@@ -20525,6 +20555,9 @@ void bgp_vty_init(void)
        install_element(BGP_NODE, &neighbor_dont_capability_negotiate_cmd);
        install_element(BGP_NODE, &no_neighbor_dont_capability_negotiate_cmd);
 
+       /* "neighbor capability fqdn" command. */
+       install_element(BGP_NODE, &neighbor_capability_fqdn_cmd);
+
        /* "neighbor ebgp-multihop" commands. */
        install_element(BGP_NODE, &neighbor_ebgp_multihop_cmd);
        install_element(BGP_NODE, &neighbor_ebgp_multihop_ttl_cmd);
index 90ac529f8cfbaf268f9bafd5149f90f8af648692..58514566ef8f570a21d41d9792bcca3c3d505691 100644 (file)
@@ -1535,6 +1535,9 @@ struct peer *peer_new(struct bgp *bgp)
        if (CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS))
                SET_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS);
 
+       SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_FQDN);
+       SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_FQDN);
+
        /* Initialize per peer bgp GR FSM */
        bgp_peer_gr_init(peer);
 
@@ -4571,6 +4574,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
        {PEER_FLAG_AIGP, 0, peer_change_none},
        {PEER_FLAG_GRACEFUL_SHUTDOWN, 0, peer_change_none},
        {PEER_FLAG_CAPABILITY_SOFT_VERSION, 0, peer_change_none},
+       {PEER_FLAG_CAPABILITY_FQDN, 0, peer_change_reset},
        {0, 0, 0}};
 
 static const struct peer_flag_action peer_af_flag_action_list[] = {
index 098a4e0f702ad7518d76336b1391ef779b1622fd..202cf7e113a08d5e26eea71eeb74031bb68e6319 100644 (file)
@@ -1460,6 +1460,7 @@ struct peer {
 #define PEER_FLAG_AIGP (1ULL << 34)
 #define PEER_FLAG_GRACEFUL_SHUTDOWN (1ULL << 35)
 #define PEER_FLAG_CAPABILITY_SOFT_VERSION (1ULL << 36)
+#define PEER_FLAG_CAPABILITY_FQDN (1ULL << 37)  /* fqdn capability */
 
        /*
         *GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART
index 231ecd2066252e990a789e3ee342d6a9b25a3a57..12c2f1103abecc78114c68cdc10193d696f9984d 100644 (file)
@@ -282,6 +282,13 @@ static struct test_peer_attr test_peer_attrs[] = {
                .u.flag = PEER_FLAG_DONT_CAPABILITY,
                .type = PEER_AT_GLOBAL_FLAG,
        },
+       {
+               .cmd = "capability fqdn",
+               .u.flag = PEER_FLAG_CAPABILITY_FQDN,
+               .type = PEER_AT_GLOBAL_FLAG,
+               .o.invert_peer = true,
+               .o.invert_group = true,
+       },
        {
                .cmd = "local-as",
                .peer_cmd = "local-as 1",
index bd8b06e2f0526204cd235556f00e5331bcade6a1..b1f88d2ce1967327c3fffe6e2857359baea49abb 100644 (file)
@@ -15,6 +15,7 @@ TestFlag.okfail("peer\\capability extended-nexthop")
 TestFlag.okfail("peer\\description")
 TestFlag.okfail("peer\\disable-connected-check")
 TestFlag.okfail("peer\\dont-capability-negotiate")
+TestFlag.okfail("peer\\capability fqdn")
 TestFlag.okfail("peer\\local-as")
 TestFlag.okfail("peer\\local-as 1 no-prepend")
 TestFlag.okfail("peer\\local-as 1 no-prepend replace-as")