]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_attr.c
Merge pull request #12795 from pguibert6WIND/vpnv6_nexthop_encoding
[mirror_frr.git] / bgpd / bgp_attr.c
index 572475f06856a5e4258c64506860ae849c9268b0..fcfb1d64e0fd954bfe19200e06773474b56c8be8 100644 (file)
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* BGP attributes management routines.
  * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -1069,7 +1054,7 @@ struct attr *bgp_attr_default_set(struct attr *attr, struct bgp *bgp,
 
        attr->origin = origin;
        attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
-       attr->aspath = aspath_empty();
+       attr->aspath = aspath_empty(bgp->asnotation);
        attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
        attr->weight = BGP_ATTR_DEFAULT_WEIGHT;
        attr->tag = 0;
@@ -1107,7 +1092,7 @@ struct attr *bgp_attr_aggregate_intern(
        if (aspath)
                attr.aspath = aspath_intern(aspath);
        else
-               attr.aspath = aspath_empty();
+               attr.aspath = aspath_empty(bgp->asnotation);
        attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
 
        /* Next hop attribute.  */
@@ -1605,15 +1590,19 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
        struct attr *const attr = args->attr;
        struct peer *const peer = args->peer;
        const bgp_size_t length = args->length;
+       enum asnotation_mode asnotation;
 
+       asnotation = bgp_get_asnotation(
+               args->peer && args->peer->bgp ? args->peer->bgp : NULL);
        /*
         * peer with AS4 => will get 4Byte ASnums
         * otherwise, will get 16 Bit
         */
-       attr->aspath = aspath_parse(
-               peer->curr, length,
-               CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
-                       && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV));
+       attr->aspath =
+               aspath_parse(peer->curr, length,
+                            CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) &&
+                                    CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV),
+                            asnotation);
 
        /* In case of IBGP, length will be zero. */
        if (!attr->aspath) {
@@ -1629,7 +1618,8 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
         * such messages, conformant BGP speakers SHOULD use the "Treat-as-
         * withdraw" error handling behavior as per [RFC7606].
         */
-       if (peer->bgp->reject_as_sets && aspath_check_as_sets(attr->aspath)) {
+       if (peer->bgp && peer->bgp->reject_as_sets &&
+           aspath_check_as_sets(attr->aspath)) {
                flog_err(EC_BGP_ATTR_MAL_AS_PATH,
                         "AS_SET and AS_CONFED_SET are deprecated from %pBP",
                         peer);
@@ -1705,8 +1695,11 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
        struct peer *const peer = args->peer;
        struct attr *const attr = args->attr;
        const bgp_size_t length = args->length;
+       enum asnotation_mode asnotation;
+
+       asnotation = bgp_get_asnotation(peer->bgp);
 
-       *as4_path = aspath_parse(peer->curr, length, 1);
+       *as4_path = aspath_parse(peer->curr, length, 1, asnotation);
 
        /* In case of IBGP, length will be zero. */
        if (!*as4_path) {
@@ -3983,23 +3976,21 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
                        }
                } break;
                case SAFI_MPLS_VPN: {
+                       if (attr->mp_nexthop_len ==
+                           BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
+                               stream_putc(s, attr->mp_nexthop_len);
+                       else
+                               stream_putc(s, BGP_ATTR_NHLEN_VPNV6_GLOBAL);
+                       stream_putl(s, 0); /* RD = 0, per RFC */
+                       stream_putl(s, 0);
+                       stream_put(s, &attr->mp_nexthop_global,
+                                  IPV6_MAX_BYTELEN);
                        if (attr->mp_nexthop_len ==
                            BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
-                               stream_putc(s, 48);
-                               stream_putl(s, 0); /* RD = 0, per RFC */
-                               stream_putl(s, 0);
-                               stream_put(s, &attr->mp_nexthop_global,
-                                          IPV6_MAX_BYTELEN);
                                stream_putl(s, 0); /* RD = 0, per RFC */
                                stream_putl(s, 0);
                                stream_put(s, &attr->mp_nexthop_local,
                                           IPV6_MAX_BYTELEN);
-                       } else {
-                               stream_putc(s, 24);
-                               stream_putl(s, 0); /* RD = 0, per RFC */
-                               stream_putl(s, 0);
-                               stream_put(s, &attr->mp_nexthop_global,
-                                          IPV6_MAX_BYTELEN);
                        }
                } break;
                case SAFI_ENCAP: