back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_ecommunity.h (source / functions) Hit Total Coverage
Test: test_bgp_aspath_zero.py::BGPAggregatorZero Lines: 0 42 0.0 %
Date: 2023-02-24 18:36:48 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /* BGP Extended Communities Attribute.
       2             :  * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #ifndef _QUAGGA_BGP_ECOMMUNITY_H
      22             : #define _QUAGGA_BGP_ECOMMUNITY_H
      23             : 
      24             : #include "bgpd/bgp_route.h"
      25             : #include "bgpd/bgp_rpki.h"
      26             : #include "bgpd/bgpd.h"
      27             : 
      28             : /* Refer to rfc7153 for the IANA registry definitions. These are
      29             :  * updated by other standards like rfc7674.
      30             :  */
      31             : /* High-order octet of the Extended Communities type field.  */
      32             : #define ECOMMUNITY_ENCODE_AS                0x00
      33             : #define ECOMMUNITY_ENCODE_IP                0x01
      34             : #define ECOMMUNITY_ENCODE_AS4               0x02
      35             : #define ECOMMUNITY_ENCODE_OPAQUE            0x03
      36             : #define ECOMMUNITY_ENCODE_EVPN              0x06
      37             : #define ECOMMUNITY_ENCODE_REDIRECT_IP_NH    0x08 /* Flow Spec */
      38             : /* Generic Transitive Experimental */
      39             : #define ECOMMUNITY_ENCODE_TRANS_EXP         0x80
      40             : 
      41             : /* RFC7674 */
      42             : #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 0x81
      43             : #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 0x82
      44             : 
      45             : /* Non-transitive extended community types. */
      46             : #define ECOMMUNITY_ENCODE_AS_NON_TRANS      0x40
      47             : #define ECOMMUNITY_ENCODE_IP_NON_TRANS      0x41
      48             : #define ECOMMUNITY_ENCODE_AS4_NON_TRANS     0x42
      49             : #define ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS  0x43
      50             : 
      51             : /* Low-order octet of the Extended Communities type field.  */
      52             : /* Note: This really depends on the high-order octet. This means that
      53             :  * multiple definitions for the same value are possible.
      54             :  */
      55             : #define ECOMMUNITY_ORIGIN_VALIDATION_STATE  0x00
      56             : #define ECOMMUNITY_ROUTE_TARGET             0x02
      57             : #define ECOMMUNITY_SITE_ORIGIN              0x03
      58             : #define ECOMMUNITY_LINK_BANDWIDTH           0x04
      59             : #define ECOMMUNITY_TRAFFIC_RATE             0x06 /* Flow Spec */
      60             : #define ECOMMUNITY_TRAFFIC_ACTION           0x07
      61             : #define ECOMMUNITY_REDIRECT_VRF             0x08
      62             : #define ECOMMUNITY_TRAFFIC_MARKING          0x09
      63             : #define ECOMMUNITY_REDIRECT_IP_NH           0x00
      64             : /* from IANA: bgp-extended-communities/bgp-extended-communities.xhtml
      65             :  * 0x0c Flow-spec Redirect to IPv4 - draft-ietf-idr-flowspec-redirect
      66             :  */
      67             : #define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4   0x0c
      68             : /* from draft-ietf-idr-flow-spec-v6-09
      69             :  * 0x0b Flow-spec Redirect to IPv6
      70             :  */
      71             : #define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6   0x0b
      72             : 
      73             : /* Low-order octet of the Extended Communities type field for EVPN types */
      74             : #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY  0x00
      75             : #define ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL    0x01
      76             : #define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02
      77             : #define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC    0x03
      78             : #define ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION 0x06
      79             : #define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW       0x0d
      80             : #define ECOMMUNITY_EVPN_SUBTYPE_ND           0x08
      81             : 
      82             : #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
      83             : 
      84             : /* DF alg bits - only lower 5 bits are applicable */
      85             : #define ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS 0x1f
      86             : 
      87             : #define ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG   0x01
      88             : #define ECOMMUNITY_EVPN_SUBTYPE_ND_OVERRIDE_FLAG 0x02
      89             : #define ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG       0x04
      90             : 
      91             : #define ECOMMUNITY_EVPN_SUBTYPE_ESI_SA_FLAG (1 << 0) /* single-active */
      92             : 
      93             : /* Low-order octet of the Extended Communities type field for OPAQUE types */
      94             : #define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP     0x0c
      95             : 
      96             : /* Extended communities attribute string format.  */
      97             : #define ECOMMUNITY_FORMAT_ROUTE_MAP            0
      98             : #define ECOMMUNITY_FORMAT_COMMUNITY_LIST       1
      99             : #define ECOMMUNITY_FORMAT_DISPLAY              2
     100             : 
     101             : /* Extended Communities value is eight octet long.  */
     102             : #define ECOMMUNITY_SIZE                        8
     103             : #define IPV6_ECOMMUNITY_SIZE                  20
     104             : 
     105             : /* Extended Community Origin Validation State */
     106             : enum ecommunity_origin_validation_states {
     107             :         ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID,
     108             :         ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND,
     109             :         ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID,
     110             :         ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED
     111             : };
     112             : 
     113             : /* Extended Communities type flag.  */
     114             : #define ECOMMUNITY_FLAG_NON_TRANSITIVE      0x40
     115             : 
     116             : /* Extended Community readable string length */
     117             : #define ECOMMUNITY_STRLEN 64
     118             : 
     119             : /* Extended Communities attribute.  */
     120             : struct ecommunity {
     121             :         /* Reference counter.  */
     122             :         unsigned long refcnt;
     123             : 
     124             :         /* Size of Each Unit of Extended Communities attribute.
     125             :          * to differentiate between IPv6 ext comm and ext comm
     126             :          */
     127             :         uint8_t unit_size;
     128             : 
     129             :         /* Size of Extended Communities attribute.  */
     130             :         uint32_t size;
     131             : 
     132             :         /* Extended Communities value.  */
     133             :         uint8_t *val;
     134             : 
     135             :         /* Human readable format string.  */
     136             :         char *str;
     137             : 
     138             :         /* Disable IEEE floating-point encoding for extended community */
     139             :         bool disable_ieee_floating;
     140             : };
     141             : 
     142             : struct ecommunity_as {
     143             :         as_t as;
     144             :         uint32_t val;
     145             : };
     146             : 
     147             : struct ecommunity_ip {
     148             :         struct in_addr ip;
     149             :         uint16_t val;
     150             : };
     151             : 
     152             : struct ecommunity_ip6 {
     153             :         struct in6_addr ip;
     154             :         uint16_t val;
     155             : };
     156             : 
     157             : /* Extended community value is eight octet.  */
     158             : struct ecommunity_val {
     159             :         char val[ECOMMUNITY_SIZE];
     160             : };
     161             : 
     162             : /* IPv6 Extended community value is eight octet.  */
     163             : struct ecommunity_val_ipv6 {
     164             :         char val[IPV6_ECOMMUNITY_SIZE];
     165             : };
     166             : 
     167             : #define ecom_length_size(X, Y)    ((X)->size * (Y))
     168             : 
     169             : /*
     170             :  * Encode BGP Route Target AS:nn.
     171             :  */
     172           0 : static inline void encode_route_target_as(as_t as, uint32_t val,
     173             :                                           struct ecommunity_val *eval)
     174             : {
     175           0 :         eval->val[0] = ECOMMUNITY_ENCODE_AS;
     176           0 :         eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
     177           0 :         eval->val[2] = (as >> 8) & 0xff;
     178           0 :         eval->val[3] = as & 0xff;
     179           0 :         eval->val[4] = (val >> 24) & 0xff;
     180           0 :         eval->val[5] = (val >> 16) & 0xff;
     181           0 :         eval->val[6] = (val >> 8) & 0xff;
     182           0 :         eval->val[7] = val & 0xff;
     183             : }
     184             : 
     185             : /*
     186             :  * Encode BGP Route Target IP:nn.
     187             :  */
     188             : static inline void encode_route_target_ip(struct in_addr ip, uint16_t val,
     189             :                                           struct ecommunity_val *eval)
     190             : {
     191             :         eval->val[0] = ECOMMUNITY_ENCODE_IP;
     192             :         eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
     193             :         memcpy(&eval->val[2], &ip, sizeof(struct in_addr));
     194             :         eval->val[6] = (val >> 8) & 0xff;
     195             :         eval->val[7] = val & 0xff;
     196             : }
     197             : 
     198             : /*
     199             :  * Encode BGP Route Target AS4:nn.
     200             :  */
     201             : static inline void encode_route_target_as4(as_t as, uint16_t val,
     202             :                                            struct ecommunity_val *eval)
     203             : {
     204             :         eval->val[0] = ECOMMUNITY_ENCODE_AS4;
     205             :         eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
     206             :         eval->val[2] = (as >> 24) & 0xff;
     207             :         eval->val[3] = (as >> 16) & 0xff;
     208             :         eval->val[4] = (as >> 8) & 0xff;
     209             :         eval->val[5] = as & 0xff;
     210             :         eval->val[6] = (val >> 8) & 0xff;
     211             :         eval->val[7] = val & 0xff;
     212             : }
     213             : 
     214             : /* Helper function to convert uint32 to IEEE-754 Floating Point */
     215           0 : static uint32_t uint32_to_ieee_float_uint32(uint32_t u)
     216             : {
     217           0 :         union {
     218             :                 float r;
     219             :                 uint32_t d;
     220           0 :         } f = {.r = (float)u};
     221             : 
     222           0 :         return f.d;
     223             : }
     224             : 
     225             : /*
     226             :  * Encode BGP Link Bandwidth extended community
     227             :  *  bandwidth (bw) is in bytes-per-sec
     228             :  */
     229           0 : static inline void encode_lb_extcomm(as_t as, uint32_t bw, bool non_trans,
     230             :                                      struct ecommunity_val *eval,
     231             :                                      bool disable_ieee_floating)
     232             : {
     233           0 :         uint32_t bandwidth =
     234           0 :                 disable_ieee_floating ? bw : uint32_to_ieee_float_uint32(bw);
     235             : 
     236           0 :         memset(eval, 0, sizeof(*eval));
     237           0 :         eval->val[0] = ECOMMUNITY_ENCODE_AS;
     238           0 :         if (non_trans)
     239           0 :                 eval->val[0] |= ECOMMUNITY_FLAG_NON_TRANSITIVE;
     240           0 :         eval->val[1] = ECOMMUNITY_LINK_BANDWIDTH;
     241           0 :         eval->val[2] = (as >> 8) & 0xff;
     242           0 :         eval->val[3] = as & 0xff;
     243           0 :         eval->val[4] = (bandwidth >> 24) & 0xff;
     244           0 :         eval->val[5] = (bandwidth >> 16) & 0xff;
     245           0 :         eval->val[6] = (bandwidth >> 8) & 0xff;
     246           0 :         eval->val[7] = bandwidth & 0xff;
     247           0 : }
     248             : 
     249           0 : static inline void encode_origin_validation_state(enum rpki_states state,
     250             :                                                   struct ecommunity_val *eval)
     251             : {
     252           0 :         enum ecommunity_origin_validation_states ovs_state =
     253             :                 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED;
     254             : 
     255           0 :         switch (state) {
     256             :         case RPKI_VALID:
     257             :                 ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID;
     258             :                 break;
     259             :         case RPKI_NOTFOUND:
     260             :                 ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND;
     261             :                 break;
     262             :         case RPKI_INVALID:
     263             :                 ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID;
     264             :                 break;
     265             :         case RPKI_NOT_BEING_USED:
     266             :                 break;
     267             :         }
     268             : 
     269           0 :         memset(eval, 0, sizeof(*eval));
     270           0 :         eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS;
     271           0 :         eval->val[1] = ECOMMUNITY_ORIGIN_VALIDATION_STATE;
     272           0 :         eval->val[7] = ovs_state;
     273           0 : }
     274             : 
     275             : extern void ecommunity_init(void);
     276             : extern void ecommunity_finish(void);
     277             : extern void ecommunity_free(struct ecommunity **);
     278             : extern struct ecommunity *ecommunity_parse(uint8_t *, unsigned short,
     279             :                                            bool disable_ieee_floating);
     280             : extern struct ecommunity *ecommunity_parse_ipv6(uint8_t *pnt,
     281             :                                                 unsigned short length,
     282             :                                                 bool disable_ieee_floating);
     283             : extern struct ecommunity *ecommunity_dup(struct ecommunity *);
     284             : extern struct ecommunity *ecommunity_merge(struct ecommunity *,
     285             :                                            struct ecommunity *);
     286             : extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
     287             : extern struct ecommunity *ecommunity_intern(struct ecommunity *);
     288             : extern bool ecommunity_cmp(const void *arg1, const void *arg2);
     289             : extern void ecommunity_unintern(struct ecommunity **ecommunity);
     290             : extern unsigned int ecommunity_hash_make(const void *);
     291             : extern struct ecommunity *ecommunity_str2com(const char *, int, int);
     292             : extern struct ecommunity *ecommunity_str2com_ipv6(const char *str, int type,
     293             :                                                   int keyword_included);
     294             : extern char *ecommunity_ecom2str(struct ecommunity *, int, int);
     295             : extern void ecommunity_strfree(char **s);
     296             : extern bool ecommunity_include(struct ecommunity *e1, struct ecommunity *e2);
     297             : extern bool ecommunity_match(const struct ecommunity *,
     298             :                              const struct ecommunity *);
     299             : extern char *ecommunity_str(struct ecommunity *);
     300             : extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *,
     301             :                                                 uint8_t, uint8_t);
     302             : 
     303             : extern bool ecommunity_add_val(struct ecommunity *ecom,
     304             :                                struct ecommunity_val *eval,
     305             :                                bool unique, bool overwrite);
     306             : extern bool ecommunity_add_val_ipv6(struct ecommunity *ecom,
     307             :                                     struct ecommunity_val_ipv6 *eval,
     308             :                                     bool unique, bool overwrite);
     309             : 
     310             : /* for vpn */
     311             : extern struct ecommunity *ecommunity_new(void);
     312             : extern bool ecommunity_strip(struct ecommunity *ecom, uint8_t type,
     313             :                              uint8_t subtype);
     314             : extern struct ecommunity *ecommunity_new(void);
     315             : extern bool ecommunity_del_val(struct ecommunity *ecom,
     316             :                                struct ecommunity_val *eval);
     317             : struct bgp_pbr_entry_action;
     318             : extern int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
     319             :                                       struct bgp_pbr_entry_action *api,
     320             :                                       afi_t afi);
     321             : 
     322             : extern void bgp_compute_aggregate_ecommunity(
     323             :                                         struct bgp_aggregate *aggregate,
     324             :                                         struct ecommunity *ecommunity);
     325             : 
     326             : extern void bgp_compute_aggregate_ecommunity_hash(
     327             :                                         struct bgp_aggregate *aggregate,
     328             :                                         struct ecommunity *ecommunity);
     329             : extern void bgp_compute_aggregate_ecommunity_val(
     330             :                                         struct bgp_aggregate *aggregate);
     331             : extern void bgp_remove_ecommunity_from_aggregate(
     332             :                                         struct bgp_aggregate *aggregate,
     333             :                                         struct ecommunity *ecommunity);
     334             : extern void bgp_remove_ecomm_from_aggregate_hash(
     335             :                                         struct bgp_aggregate *aggregate,
     336             :                                         struct ecommunity *ecommunity);
     337             : extern void bgp_aggr_ecommunity_remove(void *arg);
     338             : extern const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom,
     339             :                                                 uint32_t *bw);
     340             : extern struct ecommunity *ecommunity_replace_linkbw(as_t as,
     341             :                                                     struct ecommunity *ecom,
     342             :                                                     uint64_t cum_bw,
     343             :                                                     bool disable_ieee_floating);
     344             : 
     345           0 : static inline void ecommunity_strip_rts(struct ecommunity *ecom)
     346             : {
     347           0 :         uint8_t subtype = ECOMMUNITY_ROUTE_TARGET;
     348             : 
     349           0 :         ecommunity_strip(ecom, ECOMMUNITY_ENCODE_AS, subtype);
     350           0 :         ecommunity_strip(ecom, ECOMMUNITY_ENCODE_IP, subtype);
     351           0 :         ecommunity_strip(ecom, ECOMMUNITY_ENCODE_AS4, subtype);
     352           0 : }
     353             : extern struct ecommunity *
     354             : ecommunity_add_origin_validation_state(enum rpki_states rpki_state,
     355             :                                        struct ecommunity *ecom);
     356             : #endif /* _QUAGGA_BGP_ECOMMUNITY_H */

Generated by: LCOV version v1.16-topotato