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 | |
Lou Berger | c374178 | 2016-01-12 13:42:01 -0500 | [diff] [blame] | 50 | struct bgp_attr_encap_subtlv { |
| 51 | struct bgp_attr_encap_subtlv *next; /* for chaining */ |
| 52 | uint16_t type; |
| 53 | uint16_t length; |
| 54 | uint8_t value[1]; /* will be extended */ |
| 55 | }; |
| 56 | |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 57 | /* Additional/uncommon BGP attributes. |
| 58 | * lazily allocated as and when a struct attr |
| 59 | * requires it. |
| 60 | */ |
| 61 | struct attr_extra |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 62 | { |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 63 | /* Multi-Protocol Nexthop, AFI IPv6 */ |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 64 | struct in6_addr mp_nexthop_global; |
| 65 | struct in6_addr mp_nexthop_local; |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 66 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 67 | /* Extended Communities attribute. */ |
| 68 | struct ecommunity *ecommunity; |
Job Snijders | 3334bab | 2017-01-20 14:47:12 +0000 | [diff] [blame^] | 69 | |
| 70 | /* Large Communities attribute. */ |
| 71 | struct lcommunity *lcommunity; |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 72 | |
| 73 | /* Route-Reflector Cluster attribute */ |
| 74 | struct cluster_list *cluster; |
| 75 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 76 | /* Unknown transitive attribute. */ |
| 77 | struct transit *transit; |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 78 | |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 79 | struct in_addr mp_nexthop_global_in; |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 80 | |
| 81 | /* Aggregator Router ID attribute */ |
| 82 | struct in_addr aggregator_addr; |
| 83 | |
| 84 | /* Route Reflector Originator attribute */ |
| 85 | struct in_addr originator_id; |
| 86 | |
| 87 | /* Local weight, not actually an attribute */ |
| 88 | u_int32_t weight; |
| 89 | |
| 90 | /* Aggregator ASN */ |
| 91 | as_t aggregator_as; |
| 92 | |
| 93 | /* MP Nexthop length */ |
| 94 | u_char mp_nexthop_len; |
Lou Berger | c374178 | 2016-01-12 13:42:01 -0500 | [diff] [blame] | 95 | |
| 96 | uint16_t encap_tunneltype; /* grr */ |
| 97 | struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */ |
Piotr Chytła | 605aa33 | 2015-12-01 10:03:54 -0500 | [diff] [blame] | 98 | |
| 99 | /* route tag */ |
Paul Jakma | 96d1060 | 2016-07-01 14:23:45 +0100 | [diff] [blame] | 100 | route_tag_t tag; |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 101 | }; |
| 102 | |
| 103 | /* BGP core attribute structure. */ |
| 104 | struct attr |
| 105 | { |
| 106 | /* AS Path structure */ |
| 107 | struct aspath *aspath; |
| 108 | |
| 109 | /* Community structure */ |
| 110 | struct community *community; |
| 111 | |
| 112 | /* Lazily allocated pointer to extra attributes */ |
| 113 | struct attr_extra *extra; |
| 114 | |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 115 | /* Reference count of this attribute. */ |
| 116 | unsigned long refcnt; |
| 117 | |
| 118 | /* Flag of attribute is set or not. */ |
| 119 | u_int32_t flag; |
| 120 | |
| 121 | /* Apart from in6_addr, the remaining static attributes */ |
| 122 | struct in_addr nexthop; |
| 123 | u_int32_t med; |
| 124 | u_int32_t local_pref; |
Paul Jakma | 4136717 | 2007-08-06 15:24:51 +0000 | [diff] [blame] | 125 | |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 126 | /* Path origin attribute */ |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 127 | u_char origin; |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 128 | }; |
| 129 | |
| 130 | /* Router Reflector related structure. */ |
| 131 | struct cluster_list |
| 132 | { |
| 133 | unsigned long refcnt; |
| 134 | int length; |
| 135 | struct in_addr *list; |
| 136 | }; |
| 137 | |
| 138 | /* Unknown transit attribute. */ |
| 139 | struct transit |
| 140 | { |
| 141 | unsigned long refcnt; |
| 142 | int length; |
| 143 | u_char *val; |
| 144 | }; |
| 145 | |
| 146 | #define ATTR_FLAG_BIT(X) (1 << ((X) - 1)) |
| 147 | |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 148 | typedef enum { |
| 149 | BGP_ATTR_PARSE_PROCEED = 0, |
| 150 | BGP_ATTR_PARSE_ERROR = -1, |
| 151 | BGP_ATTR_PARSE_WITHDRAW = -2, |
David Lamparter | f57000c | 2014-06-04 01:01:10 +0200 | [diff] [blame] | 152 | |
| 153 | /* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR */ |
| 154 | BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3, |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 155 | } bgp_attr_parse_ret_t; |
| 156 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 157 | /* Prototypes. */ |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 158 | extern void bgp_attr_init (void); |
Chris Caputo | 228da42 | 2009-07-18 05:44:03 +0000 | [diff] [blame] | 159 | extern void bgp_attr_finish (void); |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 160 | extern bgp_attr_parse_ret_t bgp_attr_parse (struct peer *, struct attr *, |
| 161 | bgp_size_t, struct bgp_nlri *, |
| 162 | struct bgp_nlri *); |
Paul Jakma | fb982c2 | 2007-05-04 20:15:47 +0000 | [diff] [blame] | 163 | extern struct attr_extra *bgp_attr_extra_get (struct attr *); |
| 164 | extern void bgp_attr_extra_free (struct attr *); |
| 165 | extern void bgp_attr_dup (struct attr *, struct attr *); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 166 | extern struct attr *bgp_attr_intern (struct attr *attr); |
Paul Jakma | b881c70 | 2010-11-23 16:35:42 +0000 | [diff] [blame] | 167 | extern void bgp_attr_unintern_sub (struct attr *); |
Paul Jakma | f6f434b | 2010-11-23 21:28:03 +0000 | [diff] [blame] | 168 | extern void bgp_attr_unintern (struct attr **); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 169 | extern void bgp_attr_flush (struct attr *); |
| 170 | extern struct attr *bgp_attr_default_set (struct attr *attr, u_char); |
| 171 | extern struct attr *bgp_attr_default_intern (u_char); |
| 172 | extern struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char, |
paul | 5228ad2 | 2004-06-04 17:58:18 +0000 | [diff] [blame] | 173 | struct aspath *, |
Daniel Walton | f2eb9ca | 2015-05-19 17:47:21 -0700 | [diff] [blame] | 174 | struct community *, int as_set, u_char); |
Pradosh Mohapatra | 8c71e48 | 2014-01-15 06:57:57 +0000 | [diff] [blame] | 175 | extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, |
| 176 | struct stream *, struct attr *, |
| 177 | struct prefix *, afi_t, safi_t, |
| 178 | struct peer *, struct prefix_rd *, |
| 179 | u_char *); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 180 | extern void bgp_dump_routes_attr (struct stream *, struct attr *, |
| 181 | struct prefix *); |
Stephen Hemminger | ffe11cf | 2008-08-14 16:25:25 +0100 | [diff] [blame] | 182 | extern int attrhash_cmp (const void *, const void *); |
Paul Jakma | 923de65 | 2007-04-29 18:25:17 +0000 | [diff] [blame] | 183 | extern unsigned int attrhash_key_make (void *); |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 184 | extern void attr_show_all (struct vty *); |
Paul Jakma | cbdfbaa | 2006-03-30 13:20:48 +0000 | [diff] [blame] | 185 | extern unsigned long int attr_count (void); |
| 186 | extern unsigned long int attr_unknown_count (void); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 187 | |
| 188 | /* Cluster list prototypes. */ |
paul | 94f2b39 | 2005-06-28 12:44:16 +0000 | [diff] [blame] | 189 | extern int cluster_loop_check (struct cluster_list *, struct in_addr); |
| 190 | extern void cluster_unintern (struct cluster_list *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 191 | |
| 192 | /* Transit attribute prototypes. */ |
| 193 | void transit_unintern (struct transit *); |
paul | 00d252c | 2005-05-23 14:19:54 +0000 | [diff] [blame] | 194 | |
Paul Jakma | 835315b | 2012-01-18 12:28:30 +0000 | [diff] [blame] | 195 | /* Below exported for unit-test purposes only */ |
| 196 | struct bgp_attr_parser_args { |
| 197 | struct peer *peer; |
| 198 | bgp_size_t length; /* attribute data length; */ |
| 199 | bgp_size_t total; /* total length, inc header */ |
| 200 | struct attr *attr; |
| 201 | u_int8_t type; |
| 202 | u_int8_t flags; |
| 203 | u_char *startp; |
| 204 | }; |
| 205 | extern int bgp_mp_reach_parse (struct bgp_attr_parser_args *args, |
| 206 | struct bgp_nlri *); |
| 207 | extern int bgp_mp_unreach_parse (struct bgp_attr_parser_args *args, |
| 208 | struct bgp_nlri *); |
Paul Jakma | 0329280 | 2008-06-07 20:37:10 +0000 | [diff] [blame] | 209 | |
Lou Berger | c374178 | 2016-01-12 13:42:01 -0500 | [diff] [blame] | 210 | extern struct bgp_attr_encap_subtlv * |
| 211 | encap_tlv_dup(struct bgp_attr_encap_subtlv *orig); |
| 212 | |
| 213 | extern void |
| 214 | bgp_attr_flush_encap(struct attr *attr); |
| 215 | |
Pradosh Mohapatra | 8c71e48 | 2014-01-15 06:57:57 +0000 | [diff] [blame] | 216 | /** |
| 217 | * Set of functions to encode MP_REACH_NLRI and MP_UNREACH_NLRI attributes. |
| 218 | * Typical call sequence is to call _start(), followed by multiple _prefix(), |
| 219 | * one for each NLRI that needs to be encoded into the UPDATE message, and |
| 220 | * finally the _end() function. |
| 221 | */ |
| 222 | extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi, |
| 223 | struct attr *attr); |
| 224 | extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, |
| 225 | struct prefix *p, struct prefix_rd *prd, |
| 226 | u_char *tag); |
Lou Berger | 050defe | 2016-01-12 13:41:59 -0500 | [diff] [blame] | 227 | extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, |
| 228 | struct prefix *p); |
Pradosh Mohapatra | 8c71e48 | 2014-01-15 06:57:57 +0000 | [diff] [blame] | 229 | extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep); |
| 230 | |
| 231 | extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi, |
| 232 | safi_t safi); |
| 233 | extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p, |
| 234 | afi_t afi, safi_t safi, struct prefix_rd *prd, |
| 235 | u_char *tag); |
| 236 | extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt); |
| 237 | |
paul | 00d252c | 2005-05-23 14:19:54 +0000 | [diff] [blame] | 238 | #endif /* _QUAGGA_BGP_ATTR_H */ |