paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 1 | /* BGP attributes. |
| 2 | Copyright (C) 1996, 97, 98 Kunihiro Ishiguro |
| 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 |
| 17 | along with GNU Zebra; see the file COPYING. If not, write to the Free |
| 18 | Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
| 19 | 02111-1307, USA. */ |
| 20 | |
paul | 00d252c | 2005-05-23 14:19:54 +0000 | [diff] [blame] | 21 | #ifndef _QUAGGA_BGP_ATTR_H |
| 22 | #define _QUAGGA_BGP_ATTR_H |
| 23 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 24 | /* Simple bit mapping. */ |
| 25 | #define BITMAP_NBBY 8 |
| 26 | |
| 27 | #define SET_BITMAP(MAP, NUM) \ |
| 28 | SET_FLAG (MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY)) |
| 29 | |
| 30 | #define CHECK_BITMAP(MAP, NUM) \ |
| 31 | CHECK_FLAG (MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY)) |
| 32 | |
paul | 3b42497 | 2003-10-13 09:47:32 +0000 | [diff] [blame] | 33 | #define BGP_MED_MAX UINT32_MAX |
| 34 | |
Paul Jakma | 03e214c | 2007-04-29 18:31:07 +0000 | [diff] [blame] | 35 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 36 | /* BGP Attribute type range. */ |
| 37 | #define BGP_ATTR_TYPE_RANGE 256 |
| 38 | #define BGP_ATTR_BITMAP_SIZE (BGP_ATTR_TYPE_RANGE / BITMAP_NBBY) |
| 39 | |
| 40 | /* BGP Attribute flags. */ |
| 41 | #define BGP_ATTR_FLAG_OPTIONAL 0x80 /* Attribute is optional. */ |
| 42 | #define BGP_ATTR_FLAG_TRANS 0x40 /* Attribute is transitive. */ |
| 43 | #define BGP_ATTR_FLAG_PARTIAL 0x20 /* Attribute is partial. */ |
| 44 | #define BGP_ATTR_FLAG_EXTLEN 0x10 /* Extended length flag. */ |
| 45 | |
| 46 | /* BGP attribute header must bigger than 2. */ |
Paul Jakma | 370b64a | 2007-12-22 16:49:52 +0000 | [diff] [blame] | 47 | #define BGP_ATTR_MIN_LEN 3 /* Attribute flag, type length. */ |
Paul Jakma | 03e214c | 2007-04-29 18:31:07 +0000 | [diff] [blame] | 48 | #define BGP_ATTR_DEFAULT_WEIGHT 32768 |
| 49 | |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 50 | /* Additional/uncommon BGP attributes. |
| 51 | * lazily allocated as and when a struct attr |
| 52 | * requires it. |
| 53 | */ |
| 54 | struct attr_extra |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 55 | { |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 56 | /* Multi-Protocol Nexthop, AFI IPv6 */ |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 57 | #ifdef HAVE_IPV6 |
| 58 | struct in6_addr mp_nexthop_global; |
| 59 | struct in6_addr mp_nexthop_local; |
| 60 | #endif /* HAVE_IPV6 */ |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 61 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 62 | /* Extended Communities attribute. */ |
| 63 | struct ecommunity *ecommunity; |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 64 | |
| 65 | /* Route-Reflector Cluster attribute */ |
| 66 | struct cluster_list *cluster; |
| 67 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 68 | /* Unknown transitive attribute. */ |
| 69 | struct transit *transit; |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 70 | |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 71 | struct in_addr mp_nexthop_global_in; |
| 72 | struct in_addr mp_nexthop_local_in; |
| 73 | |
| 74 | /* Aggregator Router ID attribute */ |
| 75 | struct in_addr aggregator_addr; |
| 76 | |
| 77 | /* Route Reflector Originator attribute */ |
| 78 | struct in_addr originator_id; |
| 79 | |
| 80 | /* Local weight, not actually an attribute */ |
| 81 | u_int32_t weight; |
| 82 | |
| 83 | /* Aggregator ASN */ |
| 84 | as_t aggregator_as; |
| 85 | |
| 86 | /* MP Nexthop length */ |
| 87 | u_char mp_nexthop_len; |
| 88 | }; |
| 89 | |
| 90 | /* BGP core attribute structure. */ |
| 91 | struct attr |
| 92 | { |
| 93 | /* AS Path structure */ |
| 94 | struct aspath *aspath; |
| 95 | |
| 96 | /* Community structure */ |
| 97 | struct community *community; |
| 98 | |
| 99 | /* Lazily allocated pointer to extra attributes */ |
| 100 | struct attr_extra *extra; |
| 101 | |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 102 | /* Reference count of this attribute. */ |
| 103 | unsigned long refcnt; |
| 104 | |
| 105 | /* Flag of attribute is set or not. */ |
| 106 | u_int32_t flag; |
| 107 | |
| 108 | /* Apart from in6_addr, the remaining static attributes */ |
| 109 | struct in_addr nexthop; |
| 110 | u_int32_t med; |
| 111 | u_int32_t local_pref; |
Paul Jakma | 4136717 | 2007-08-06 15:24:51 +0000 | [diff] [blame] | 112 | |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 113 | /* Path origin attribute */ |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 114 | u_char origin; |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 115 | }; |
| 116 | |
| 117 | /* Router Reflector related structure. */ |
| 118 | struct cluster_list |
| 119 | { |
| 120 | unsigned long refcnt; |
| 121 | int length; |
| 122 | struct in_addr *list; |
| 123 | }; |
| 124 | |
| 125 | /* Unknown transit attribute. */ |
| 126 | struct transit |
| 127 | { |
| 128 | unsigned long refcnt; |
| 129 | int length; |
| 130 | u_char *val; |
| 131 | }; |
| 132 | |
| 133 | #define ATTR_FLAG_BIT(X) (1 << ((X) - 1)) |
| 134 | |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 135 | typedef enum { |
| 136 | BGP_ATTR_PARSE_PROCEED = 0, |
| 137 | BGP_ATTR_PARSE_ERROR = -1, |
| 138 | BGP_ATTR_PARSE_WITHDRAW = -2, |
David Lamparter | f57000c | 2014-06-04 01:01:10 +0200 | [diff] [blame] | 139 | |
| 140 | /* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR */ |
| 141 | BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3, |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 142 | } bgp_attr_parse_ret_t; |
| 143 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 144 | /* Prototypes. */ |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 145 | extern void bgp_attr_init (void); |
Chris Caputo | 228da42 | 2009-07-18 05:44:03 +0000 | [diff] [blame] | 146 | extern void bgp_attr_finish (void); |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 147 | extern bgp_attr_parse_ret_t bgp_attr_parse (struct peer *, struct attr *, |
| 148 | bgp_size_t, struct bgp_nlri *, |
| 149 | struct bgp_nlri *); |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 150 | extern struct attr_extra *bgp_attr_extra_get (struct attr *); |
| 151 | extern void bgp_attr_extra_free (struct attr *); |
| 152 | extern void bgp_attr_dup (struct attr *, struct attr *); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 153 | extern struct attr *bgp_attr_intern (struct attr *attr); |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 154 | extern void bgp_attr_unintern_sub (struct attr *); |
Paul Jakma | f6f434b | 2010-11-23 21:28:03 +0000 | [diff] [blame] | 155 | extern void bgp_attr_unintern (struct attr **); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 156 | extern void bgp_attr_flush (struct attr *); |
| 157 | extern struct attr *bgp_attr_default_set (struct attr *attr, u_char); |
| 158 | extern struct attr *bgp_attr_default_intern (u_char); |
| 159 | extern struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char, |
paul | 5228ad2 | 2004-06-04 17:58:18 +0000 | [diff] [blame] | 160 | struct aspath *, |
| 161 | struct community *, int as_set); |
Pradosh Mohapatra | 8c71e48 | 2014-01-15 06:57:57 +0000 | [diff] [blame] | 162 | extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, |
| 163 | struct stream *, struct attr *, |
| 164 | struct prefix *, afi_t, safi_t, |
| 165 | struct peer *, struct prefix_rd *, |
| 166 | u_char *); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 167 | extern void bgp_dump_routes_attr (struct stream *, struct attr *, |
| 168 | struct prefix *); |
Stephen Hemminger | ffe11cf | 2008-08-14 16:25:25 +0100 | [diff] [blame] | 169 | extern int attrhash_cmp (const void *, const void *); |
Paul Jakma | 923de65 | 2007-04-29 18:25:17 +0000 | [diff] [blame] | 170 | extern unsigned int attrhash_key_make (void *); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 171 | extern void attr_show_all (struct vty *); |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 172 | extern unsigned long int attr_count (void); |
| 173 | extern unsigned long int attr_unknown_count (void); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 174 | |
| 175 | /* Cluster list prototypes. */ |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 176 | extern int cluster_loop_check (struct cluster_list *, struct in_addr); |
| 177 | extern void cluster_unintern (struct cluster_list *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 178 | |
| 179 | /* Transit attribute prototypes. */ |
| 180 | void transit_unintern (struct transit *); |
paul | 00d252c | 2005-05-23 14:19:54 +0000 | [diff] [blame] | 181 | |
Paul Jakma | 835315b | 2012-01-18 12:28:30 +0000 | [diff] [blame] | 182 | /* Below exported for unit-test purposes only */ |
| 183 | struct bgp_attr_parser_args { |
| 184 | struct peer *peer; |
| 185 | bgp_size_t length; /* attribute data length; */ |
| 186 | bgp_size_t total; /* total length, inc header */ |
| 187 | struct attr *attr; |
| 188 | u_int8_t type; |
| 189 | u_int8_t flags; |
| 190 | u_char *startp; |
| 191 | }; |
| 192 | extern int bgp_mp_reach_parse (struct bgp_attr_parser_args *args, |
| 193 | struct bgp_nlri *); |
| 194 | extern int bgp_mp_unreach_parse (struct bgp_attr_parser_args *args, |
| 195 | struct bgp_nlri *); |
Paul Jakma | 0329280 | 2008-06-07 20:37:10 +0000 | [diff] [blame] | 196 | |
Pradosh Mohapatra | 8c71e48 | 2014-01-15 06:57:57 +0000 | [diff] [blame] | 197 | /** |
| 198 | * Set of functions to encode MP_REACH_NLRI and MP_UNREACH_NLRI attributes. |
| 199 | * Typical call sequence is to call _start(), followed by multiple _prefix(), |
| 200 | * one for each NLRI that needs to be encoded into the UPDATE message, and |
| 201 | * finally the _end() function. |
| 202 | */ |
| 203 | extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi, |
| 204 | struct attr *attr); |
| 205 | extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, |
| 206 | struct prefix *p, struct prefix_rd *prd, |
| 207 | u_char *tag); |
Lou Berger | 050defe | 2016-01-12 13:41:59 -0500 | [diff] [blame^] | 208 | extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, |
| 209 | struct prefix *p); |
Pradosh Mohapatra | 8c71e48 | 2014-01-15 06:57:57 +0000 | [diff] [blame] | 210 | extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep); |
| 211 | |
| 212 | extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi, |
| 213 | safi_t safi); |
| 214 | extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, |
| 215 | afi_t afi, safi_t safi, struct prefix_rd *prd, |
| 216 | u_char *tag); |
| 217 | extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt); |
| 218 | |
paul | 00d252c | 2005-05-23 14:19:54 +0000 | [diff] [blame] | 219 | #endif /* _QUAGGA_BGP_ATTR_H */ |