1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* Copyright 2009-2016, LabN Consulting, L.L.C.
*
*/
/*
* Internal definitions for RFAPI. Not for use by other code
*/
#ifndef _QUAGGA_BGP_RFAPI_PRIVATE_H
#define _QUAGGA_BGP_RFAPI_PRIVATE_H
#include "lib/linklist.h"
#include "lib/skiplist.h"
#include "lib/workqueue.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_route.h"
#include "rfapi.h"
/*
* Lists of rfapi_adb. Each rfapi_adb is referenced twice:
*
* 1. each is referenced in by_lifetime
* 2. each is referenced by exactly one of: ipN_by_prefix, ip0_by_ether
*/
struct rfapi_advertised_prefixes {
struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */
struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */
struct skiplist *by_lifetime; /* all */
};
struct rfapi_descriptor {
struct agg_node *un_node; /* backref to un table */
struct rfapi_descriptor *next; /* next vn_addr */
/* supplied by client */
struct bgp *bgp; /* from rfp_start_val */
struct rfapi_ip_addr vn_addr;
struct rfapi_ip_addr un_addr;
rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */
void *cookie; /* for callbacks */
struct rfapi_tunneltype_option default_tunneltype_option;
/* supplied by matched configuration */
struct prefix_rd rd;
struct ecommunity *rt_export_list;
uint32_t response_lifetime;
/* list of prefixes currently being advertised by this nve */
struct rfapi_advertised_prefixes advertised;
time_t open_time;
uint32_t max_prefix_lifetime;
uint32_t min_prefix_lifetime;
/* reference to this nve's import table */
struct rfapi_import_table *import_table;
uint32_t monitor_count;
struct agg_table *mon; /* rfapi_monitors */
struct skiplist *mon_eth; /* ethernet monitors */
/*
* rib RIB as seen by NVE
* rib_pending RIB containing nodes with updated info chains
* rsp_times last time we sent response containing pfx
*/
uint32_t rib_prefix_count; /* pfxes with routes */
struct agg_table *rib[AFI_MAX];
struct agg_table *rib_pending[AFI_MAX];
struct work_queue *updated_responses_queue;
struct agg_table *rsp_times[AFI_MAX];
uint32_t rsp_counter; /* dedup initial rsp */
time_t rsp_time; /* dedup initial rsp */
time_t ftd_last_allowed_time; /* FTD filter */
unsigned int stat_count_nh_reachable;
unsigned int stat_count_nh_removal;
/*
* points to the original nve group structure that matched
* when this nve_descriptor was created. We use this pointer
* in rfapi_close() to find the nve group structure and
* delete its reference back to us.
*
* If the nve group structure is deleted (via configuration
* change) while this nve_descriptor exists, this rfg pointer
* will be set to NULL.
*/
struct rfapi_nve_group_cfg *rfg;
/*
* This ~7kB structure is here to permit multiple routes for
* a prefix to be injected to BGP. There are at least two
* situations where such conditions obtain:
*
* When an VNC route is exported to BGP on behalf of the set of
* NVEs that belong to the export NVE group, it is replicated
* so that there is one route per NVE (and the route's nexthop
* is the NVE's VN address).
*
* Each of these routes being injected to BGP must have a distinct
* peer pointer (otherwise, if they have the same peer pointer, each
* route will be considered an implicit waithdraw of the previous
* route injected from that peer, and the new route will replace
* rather than augment the old one(s)).
*/
struct peer *peer;
uint32_t flags;
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP 0x00000001
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 0x00000002
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN 0x00000004
#define RFAPI_HD_FLAG_PROVISIONAL 0x00000008
#define RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY 0x00000010
#define RFAPI_HD_FLAG_IS_VRF 0x00000012
};
#define RFAPI_QUEUED_FLAG(afi) \
(((afi) == AFI_IP) \
? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP \
: (((afi) == AFI_IP6) \
? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 \
: (((afi) == AFI_L2VPN) \
? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN \
: (assert(0), 0))))
struct rfapi_global_stats {
time_t last_reset;
unsigned int max_descriptors;
unsigned int count_unknown_nves;
unsigned int count_queries;
unsigned int count_queries_failed;
unsigned int max_responses; /* semantics? */
unsigned int count_registrations;
unsigned int count_registrations_failed;
unsigned int count_updated_response_updates;
unsigned int count_updated_response_deletes;
};
/*
* There is one of these per BGP instance.
*
* Radix tree is indexed by un address; follow chain and
* check vn address to get exact match.
*/
struct rfapi {
struct agg_table *un[AFI_MAX];
struct rfapi_import_table *imports; /* IPv4, IPv6 */
struct list descriptors; /* debug & resolve-nve imports */
struct rfapi_global_stats stat;
/*
* callbacks into RFP, set at startup time (bgp_rfapi_new() gets
* values from rfp_start()) or via rfapi_rfp_set_cb_methods()
* (otherwise NULL). Note that the response_cb method can also
* be overridden per-rfd (currently used only for debug/test scenarios)
*/
struct rfapi_rfp_cb_methods rfp_methods;
/*
* Import tables for Ethernet over IPSEC
*
* The skiplist keys are LNIs. Values are pointers
* to struct rfapi_import_table.
*/
struct skiplist *import_mac; /* L2 */
/*
* when exporting plain routes ("registered-nve" mode) to
* bgp unicast or zebra, we need to keep track of information
* related to expiring the routes according to the VNC lifetime
*/
struct agg_table *rt_export_bgp[AFI_MAX];
struct agg_table *rt_export_zebra[AFI_MAX];
/*
* For VNC->BGP unicast exports in CE mode, we need a
* routing table that collects all of the VPN routes
* in a single tree. The VPN rib is split up according
* to RD first, so we can't use that. This is an import
* table that matches all RTs.
*/
struct rfapi_import_table *it_ce;
/*
* when importing bgp-direct routes in resolve-nve mode,
* this list maps unicast route nexthops to their bgp_path_infos
* in the unicast table
*/
struct skiplist *resolve_nve_nexthop;
/*
* Descriptors for which rfapi_close() was called during a callback.
* They will be closed after the callback finishes.
*/
struct work_queue *deferred_close_q;
/*
* For "show vnc responses"
*/
uint32_t response_immediate_count;
uint32_t response_updated_count;
uint32_t monitor_count;
uint32_t rib_prefix_count_total;
uint32_t rib_prefix_count_total_max;
uint32_t flags;
#define RFAPI_INCALLBACK 0x00000001
void *rfp; /* from rfp_start */
};
#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) \
do { \
++(rfd)->rib_prefix_count; \
++(rfapi)->rib_prefix_count_total; \
if ((rfapi)->rib_prefix_count_total \
> (rfapi)->rib_prefix_count_total_max) \
++(rfapi)->rib_prefix_count_total_max; \
} while (0)
#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) \
do { \
--(rfd)->rib_prefix_count; \
--(rfapi)->rib_prefix_count_total; \
} while (0)
#define RFAPI_0_PREFIX(prefix) \
((((prefix)->family == AF_INET) \
? (prefix)->u.prefix4.s_addr == INADDR_ANY \
: (((prefix)->family == AF_INET6) \
? (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) \
: 0)))
#define RFAPI_0_ETHERADDR(ea) \
(((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | (ea)->octet[3] \
| (ea)->octet[4] | (ea)->octet[5]) \
== 0)
#define RFAPI_HOST_PREFIX(prefix) \
(((prefix)->family == AF_INET) \
? ((prefix)->prefixlen == IPV4_MAX_BITLEN) \
: (((prefix)->family == AF_INET6) \
? ((prefix)->prefixlen == IPV6_MAX_BITLEN) \
: 0))
extern int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
struct rfapi_ip_addr *un_addr,
struct rfapi_descriptor **rfd);
extern void
add_vnc_route(struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */
struct bgp *bgp, int safi, const struct prefix *p,
struct prefix_rd *prd, struct rfapi_ip_addr *nexthop,
uint32_t *local_pref, /* host byte order */
uint32_t *lifetime, /* host byte order */
struct bgp_tea_options *rfp_options,
struct rfapi_un_option *options_un,
struct rfapi_vn_option *options_vn,
struct ecommunity *rt_export_list, uint32_t *med, uint32_t *label,
uint8_t type, uint8_t sub_type, int flags);
#define RFAPI_AHR_NO_TUNNEL_SUBTLV 0x00000001
#define RFAPI_AHR_RFPOPT_IS_VNCTLV 0x00000002 /* hack! */
extern void del_vnc_route(struct rfapi_descriptor *rfd, struct peer *peer,
struct bgp *bgp, safi_t safi, const struct prefix *p,
struct prefix_rd *prd, uint8_t type, uint8_t sub_type,
struct rfapi_nexthop *lnh, int kill);
extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str,
struct prefix *p);
extern int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime);
extern int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p);
extern int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp);
extern void vnc_import_bgp_add_rfp_host_route_mode_resolve_nve(
struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix);
extern void vnc_import_bgp_del_rfp_host_route_mode_resolve_nve(
struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix);
extern void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p);
extern struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig);
extern struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig);
extern struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig);
extern int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1,
struct rfapi_ip_addr *a2);
extern uint32_t rfp_cost_to_localpref(uint8_t cost);
extern int rfapi_set_autord_from_vn(struct prefix_rd *rd,
struct rfapi_ip_addr *vn);
extern struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme);
extern void rfapi_nexthop_free(void *goner);
extern struct rfapi_vn_option *
rfapi_vn_options_dup(struct rfapi_vn_option *existing);
extern void rfapi_un_options_free(struct rfapi_un_option *goner);
extern void rfapi_vn_options_free(struct rfapi_vn_option *goner);
extern void vnc_add_vrf_opener(struct bgp *bgp,
struct rfapi_nve_group_cfg *rfg);
extern void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg);
/*------------------------------------------
* rfapi_extract_l2o
*
* Find Layer 2 options in an option chain
*
* input:
* pHop option chain
*
* output:
* l2o layer 2 options extracted
*
* return value:
* 0 OK
* 1 no options found
*
--------------------------------------------*/
extern int rfapi_extract_l2o(
struct bgp_tea_options *pHop, /* chain of options */
struct rfapi_l2address_option *l2o); /* return extracted value */
/*
* compaitibility to old quagga_time call
* time_t value in terms of stabilised absolute time.
* replacement for POSIX time()
*
* Please do not use this. This is kept only for
* Lou's CI in that that CI compiles against some
* private bgp code and it will just fail to compile
* without this. Use monotime()
*/
extern time_t rfapi_time(time_t *t);
DECLARE_MGROUP(RFAPI);
DECLARE_MTYPE(RFAPI_CFG);
DECLARE_MTYPE(RFAPI_GROUP_CFG);
DECLARE_MTYPE(RFAPI_L2_CFG);
DECLARE_MTYPE(RFAPI_RFP_GROUP_CFG);
DECLARE_MTYPE(RFAPI);
DECLARE_MTYPE(RFAPI_DESC);
DECLARE_MTYPE(RFAPI_IMPORTTABLE);
DECLARE_MTYPE(RFAPI_MONITOR);
DECLARE_MTYPE(RFAPI_MONITOR_ENCAP);
DECLARE_MTYPE(RFAPI_NEXTHOP);
DECLARE_MTYPE(RFAPI_VN_OPTION);
DECLARE_MTYPE(RFAPI_UN_OPTION);
DECLARE_MTYPE(RFAPI_WITHDRAW);
DECLARE_MTYPE(RFAPI_RFG_NAME);
DECLARE_MTYPE(RFAPI_ADB);
DECLARE_MTYPE(RFAPI_ETI);
DECLARE_MTYPE(RFAPI_NVE_ADDR);
DECLARE_MTYPE(RFAPI_PREFIX_BAG);
DECLARE_MTYPE(RFAPI_IT_EXTRA);
DECLARE_MTYPE(RFAPI_INFO);
DECLARE_MTYPE(RFAPI_ADDR);
DECLARE_MTYPE(RFAPI_UPDATED_RESPONSE_QUEUE);
DECLARE_MTYPE(RFAPI_RECENT_DELETE);
DECLARE_MTYPE(RFAPI_L2ADDR_OPT);
DECLARE_MTYPE(RFAPI_AP);
DECLARE_MTYPE(RFAPI_MONITOR_ETH);
/*
* Caller must supply an already-allocated rfd with the "caller"
* fields already set (vn_addr, un_addr, callback, cookie)
* The advertised_prefixes[] array elements should be NULL to
* have this function set them to newly-allocated radix trees.
*/
extern int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct rfapi_nve_group_cfg *rfg);
#endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */
|