]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_attr.c
Merge pull request #12566 from Jafaral/lsa-op
[mirror_frr.git] / bgpd / bgp_attr.c
index 337a82b9456ce93d0424eacf0c99ea0416da6433..3d93e8a1acdadb0755ce245dfb70c7e9041b9bf1 100644 (file)
@@ -825,55 +825,56 @@ bool attrhash_cmp(const void *p1, const void *p2)
                && attr1->med == attr2->med
            && attr1->local_pref == attr2->local_pref
            && attr1->rmap_change_flags == attr2->rmap_change_flags) {
-               if (attr1->aggregator_as == attr2->aggregator_as
-                   && attr1->aggregator_addr.s_addr
-                              == attr2->aggregator_addr.s_addr
-                   && attr1->weight == attr2->weight
-                   && attr1->tag == attr2->tag
-                   && attr1->label_index == attr2->label_index
-                   && attr1->mp_nexthop_len == attr2->mp_nexthop_len
-                   && bgp_attr_get_ecommunity(attr1)
-                              == bgp_attr_get_ecommunity(attr2)
-                   && bgp_attr_get_ipv6_ecommunity(attr1)
-                              == bgp_attr_get_ipv6_ecommunity(attr2)
-                   && bgp_attr_get_lcommunity(attr1)
-                                  == bgp_attr_get_lcommunity(attr2)
-                   && bgp_attr_get_cluster(attr1)
-                              == bgp_attr_get_cluster(attr2)
-                   && bgp_attr_get_transit(attr1)
-                              == bgp_attr_get_transit(attr2)
-                   && bgp_attr_get_aigp_metric(attr1)
-                              == bgp_attr_get_aigp_metric(attr2)
-                   && attr1->rmap_table_id == attr2->rmap_table_id
-                   && (attr1->encap_tunneltype == attr2->encap_tunneltype)
-                   && encap_same(attr1->encap_subtlvs, attr2->encap_subtlvs)
+               if (attr1->aggregator_as == attr2->aggregator_as &&
+                   attr1->aggregator_addr.s_addr ==
+                           attr2->aggregator_addr.s_addr &&
+                   attr1->weight == attr2->weight &&
+                   attr1->tag == attr2->tag &&
+                   attr1->label_index == attr2->label_index &&
+                   attr1->mp_nexthop_len == attr2->mp_nexthop_len &&
+                   bgp_attr_get_ecommunity(attr1) ==
+                           bgp_attr_get_ecommunity(attr2) &&
+                   bgp_attr_get_ipv6_ecommunity(attr1) ==
+                           bgp_attr_get_ipv6_ecommunity(attr2) &&
+                   bgp_attr_get_lcommunity(attr1) ==
+                           bgp_attr_get_lcommunity(attr2) &&
+                   bgp_attr_get_cluster(attr1) ==
+                           bgp_attr_get_cluster(attr2) &&
+                   bgp_attr_get_transit(attr1) ==
+                           bgp_attr_get_transit(attr2) &&
+                   bgp_attr_get_aigp_metric(attr1) ==
+                           bgp_attr_get_aigp_metric(attr2) &&
+                   attr1->rmap_table_id == attr2->rmap_table_id &&
+                   (attr1->encap_tunneltype == attr2->encap_tunneltype) &&
+                   encap_same(attr1->encap_subtlvs, attr2->encap_subtlvs)
 #ifdef ENABLE_BGP_VNC
                    && encap_same(bgp_attr_get_vnc_subtlvs(attr1),
                                  bgp_attr_get_vnc_subtlvs(attr2))
 #endif
                    && IPV6_ADDR_SAME(&attr1->mp_nexthop_global,
-                                     &attr2->mp_nexthop_global)
-                   && IPV6_ADDR_SAME(&attr1->mp_nexthop_local,
-                                     &attr2->mp_nexthop_local)
-                   && IPV4_ADDR_SAME(&attr1->mp_nexthop_global_in,
-                                     &attr2->mp_nexthop_global_in)
-                   && IPV4_ADDR_SAME(&attr1->originator_id,
-                                     &attr2->originator_id)
-                   && overlay_index_same(attr1, attr2)
-                   && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t))
-                   && attr1->es_flags == attr2->es_flags
-                   && attr1->mm_sync_seqnum == attr2->mm_sync_seqnum
-                   && attr1->df_pref == attr2->df_pref
-                   && attr1->df_alg == attr2->df_alg
-                   && attr1->nh_ifindex == attr2->nh_ifindex
-                   && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex
-                   && attr1->distance == attr2->distance
-                   && srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn)
-                   && srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn)
-                   && attr1->srte_color == attr2->srte_color
-                   && attr1->nh_type == attr2->nh_type
-                   && attr1->bh_type == attr2->bh_type
-                   && attr1->otc == attr2->otc)
+                                     &attr2->mp_nexthop_global) &&
+                   IPV6_ADDR_SAME(&attr1->mp_nexthop_local,
+                                  &attr2->mp_nexthop_local) &&
+                   IPV4_ADDR_SAME(&attr1->mp_nexthop_global_in,
+                                  &attr2->mp_nexthop_global_in) &&
+                   IPV4_ADDR_SAME(&attr1->originator_id,
+                                  &attr2->originator_id) &&
+                   overlay_index_same(attr1, attr2) &&
+                   !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t)) &&
+                   attr1->es_flags == attr2->es_flags &&
+                   attr1->mm_sync_seqnum == attr2->mm_sync_seqnum &&
+                   attr1->df_pref == attr2->df_pref &&
+                   attr1->df_alg == attr2->df_alg &&
+                   attr1->nh_ifindex == attr2->nh_ifindex &&
+                   attr1->nh_flag == attr2->nh_flag &&
+                   attr1->nh_lla_ifindex == attr2->nh_lla_ifindex &&
+                   attr1->distance == attr2->distance &&
+                   srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn) &&
+                   srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn) &&
+                   attr1->srte_color == attr2->srte_color &&
+                   attr1->nh_type == attr2->nh_type &&
+                   attr1->bh_type == attr2->bh_type &&
+                   attr1->otc == attr2->otc)
                        return true;
        }
 
@@ -2254,6 +2255,12 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
                                return BGP_ATTR_PARSE_WITHDRAW;
                        }
                        attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+                       if (if_is_operative(peer->nexthop.ifp))
+                               SET_FLAG(attr->nh_flag,
+                                        BGP_ATTR_NH_IF_OPERSTATE);
+                       else
+                               UNSET_FLAG(attr->nh_flag,
+                                          BGP_ATTR_NH_IF_OPERSTATE);
                }
                break;
        case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
@@ -2271,6 +2278,12 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
                                return BGP_ATTR_PARSE_WITHDRAW;
                        }
                        attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+                       if (if_is_operative(peer->nexthop.ifp))
+                               SET_FLAG(attr->nh_flag,
+                                        BGP_ATTR_NH_IF_OPERSTATE);
+                       else
+                               UNSET_FLAG(attr->nh_flag,
+                                          BGP_ATTR_NH_IF_OPERSTATE);
                }
                if (attr->mp_nexthop_len
                    == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
@@ -3876,7 +3889,10 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
                                stream_putc(s, attr->mp_nexthop_len);
                                stream_put_ipv4(s, attr->nexthop.s_addr);
                        }
-               default:
+                       break;
+               case SAFI_UNSPEC:
+               case SAFI_MAX:
+                       assert(!"SAFI's UNSPEC or MAX being specified are a DEV ESCAPE");
                        break;
                }
                break;
@@ -3927,17 +3943,24 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
                        break;
                case SAFI_FLOWSPEC:
                        stream_putc(s, 0); /* no nexthop for flowspec */
-               default:
+                       break;
+               case SAFI_UNSPEC:
+               case SAFI_MAX:
+                       assert(!"SAFI's UNSPEC or MAX being specified are a DEV ESCAPE");
                        break;
                }
                break;
-       default:
+       case AFI_L2VPN:
                if (safi != SAFI_FLOWSPEC)
                        flog_err(
                                EC_BGP_ATTR_NH_SEND_LEN,
                                "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
                                peer->host, afi, safi, attr->mp_nexthop_len);
                break;
+       case AFI_UNSPEC:
+       case AFI_MAX:
+               assert(!"DEV ESCAPE: AFI_UNSPEC or AFI_MAX should not be used here");
+               break;
        }
 
        /* SNPA */
@@ -3951,7 +3974,12 @@ void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
                              uint32_t num_labels, bool addpath_capable,
                              uint32_t addpath_tx_id, struct attr *attr)
 {
-       if (safi == SAFI_MPLS_VPN) {
+       switch (safi) {
+       case SAFI_UNSPEC:
+       case SAFI_MAX:
+               assert(!"Dev escape usage of SAFI_UNSPEC or MAX");
+               break;
+       case SAFI_MPLS_VPN:
                if (addpath_capable)
                        stream_putl(s, addpath_tx_id);
                /* Label, RD, Prefix write. */
@@ -3959,35 +3987,74 @@ void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
                stream_put(s, label, BGP_LABEL_BYTES);
                stream_put(s, prd->val, 8);
                stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
-       } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
-               /* EVPN prefix - contents depend on type */
-               bgp_evpn_encode_prefix(s, p, prd, label, num_labels, attr,
-                                      addpath_capable, addpath_tx_id);
-       } else if (safi == SAFI_LABELED_UNICAST) {
+               break;
+       case SAFI_EVPN:
+               if (afi == AFI_L2VPN)
+                       /* EVPN prefix - contents depend on type */
+                       bgp_evpn_encode_prefix(s, p, prd, label, num_labels,
+                                              attr, addpath_capable,
+                                              addpath_tx_id);
+               else
+                       assert(!"Add encoding bits here for other AFI's");
+               break;
+       case SAFI_LABELED_UNICAST:
                /* Prefix write with label. */
                stream_put_labeled_prefix(s, p, label, addpath_capable,
                                          addpath_tx_id);
-       } else if (safi == SAFI_FLOWSPEC) {
+               break;
+       case SAFI_FLOWSPEC:
                stream_putc(s, p->u.prefix_flowspec.prefixlen);
                stream_put(s, (const void *)p->u.prefix_flowspec.ptr,
                           p->u.prefix_flowspec.prefixlen);
-       } else
+               break;
+
+       case SAFI_UNICAST:
+       case SAFI_MULTICAST:
                stream_put_prefix_addpath(s, p, addpath_capable, addpath_tx_id);
+               break;
+       case SAFI_ENCAP:
+               assert(!"Please add proper encoding of SAFI_ENCAP");
+               break;
+       }
 }
 
 size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
                                     const struct prefix *p)
 {
        int size = PSIZE(p->prefixlen);
-       if (safi == SAFI_MPLS_VPN)
+
+       switch (safi) {
+       case SAFI_UNSPEC:
+       case SAFI_MAX:
+               assert(!"Attempting to figure size for a SAFI_UNSPEC/SAFI_MAX this is a DEV ESCAPE");
+               break;
+       case SAFI_UNICAST:
+       case SAFI_MULTICAST:
+               break;
+       case SAFI_MPLS_VPN:
                size += 88;
-       else if (safi == SAFI_LABELED_UNICAST)
+               break;
+       case SAFI_ENCAP:
+               /* This has to be wrong, but I don't know what to put here */
+               assert(!"Do we try to use this?");
+               break;
+       case SAFI_LABELED_UNICAST:
                size += BGP_LABEL_BYTES;
-       else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
-               size += 232; // TODO: Maximum possible for type-2, type-3 and
-                            // type-5
-       else if (safi == SAFI_FLOWSPEC)
+               break;
+       case SAFI_EVPN:
+               /*
+                * TODO: Maximum possible for type-2, type-3 and type-5
+                */
+               if (afi == AFI_L2VPN)
+                       size += 232;
+               else
+                       assert(!"Attempting to figure size for SAFI_EVPN and !AFI_L2VPN and FRR will not have the proper values");
+               break;
+       case SAFI_FLOWSPEC:
                size = ((struct prefix_fs *)p)->prefix.prefixlen;
+               break;
+       }
+
        return size;
 }
 
@@ -4628,7 +4695,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
        }
 
        /* AIGP */
-       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP) &&
+       if (bpi && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP) &&
            (CHECK_FLAG(peer->flags, PEER_FLAG_AIGP) ||
             peer->sort != BGP_PEER_EBGP)) {
                /* At the moment only AIGP Metric TLV exists for AIGP