2019-05-13 21:46:05 +02:00
|
|
|
/* Zebra Nexthop Group header.
|
|
|
|
* Copyright (C) 2019 Cumulus Networks, Inc.
|
|
|
|
* Donald Sharp
|
|
|
|
* Stephen Worley
|
|
|
|
*
|
|
|
|
* This file is part of FRR.
|
|
|
|
*
|
|
|
|
* FRR is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
* later version.
|
|
|
|
*
|
|
|
|
* FRR is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with FRR; see the file COPYING. If not, write to the Free
|
|
|
|
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#ifndef __ZEBRA_NHG_H__
|
|
|
|
#define __ZEBRA_NHG_H__
|
|
|
|
|
|
|
|
#include "zebra/rib.h"
|
2019-01-24 14:06:34 +01:00
|
|
|
#include "lib/nexthop_group.h"
|
2019-05-13 21:46:05 +02:00
|
|
|
|
2019-03-08 00:15:30 +01:00
|
|
|
#include "zebra/zebra_dplane.h"
|
|
|
|
|
2019-05-14 02:10:34 +02:00
|
|
|
/* This struct is used exclusively for dataplane
|
|
|
|
* interaction via a dataplane context.
|
|
|
|
*
|
|
|
|
* It is designed to mimic the netlink nexthop_grp
|
|
|
|
* struct in include/linux/nexthop.h
|
|
|
|
*/
|
2019-05-15 00:03:29 +02:00
|
|
|
struct nh_grp {
|
2019-05-14 02:10:34 +02:00
|
|
|
uint32_t id;
|
|
|
|
uint8_t weight;
|
|
|
|
};
|
|
|
|
|
2019-07-24 18:27:40 +02:00
|
|
|
PREDECL_RBTREE_UNIQ(nhg_connected_tree);
|
2019-05-14 02:10:34 +02:00
|
|
|
|
2019-01-24 14:06:34 +01:00
|
|
|
struct nhg_hash_entry {
|
2019-02-15 19:18:48 +01:00
|
|
|
uint32_t id;
|
2019-03-19 22:06:01 +01:00
|
|
|
afi_t afi;
|
2019-01-24 14:06:34 +01:00
|
|
|
vrf_id_t vrf_id;
|
2019-08-01 20:07:04 +02:00
|
|
|
int type;
|
2019-01-24 14:06:34 +01:00
|
|
|
|
2019-03-22 18:11:07 +01:00
|
|
|
struct nexthop_group *nhg;
|
2019-01-24 14:06:34 +01:00
|
|
|
|
2019-05-14 22:46:05 +02:00
|
|
|
/* If this is not a group, it
|
|
|
|
* will be a single nexthop
|
|
|
|
* and must have an interface
|
|
|
|
* associated with it.
|
|
|
|
* Otherwise, this will be null.
|
|
|
|
*/
|
|
|
|
struct interface *ifp;
|
|
|
|
|
2019-01-24 14:06:34 +01:00
|
|
|
uint32_t refcnt;
|
|
|
|
uint32_t dplane_ref;
|
2019-01-24 03:32:49 +01:00
|
|
|
|
|
|
|
uint32_t flags;
|
2019-03-21 15:43:16 +01:00
|
|
|
|
2019-05-14 02:10:34 +02:00
|
|
|
/* Dependency tree for other entries.
|
2019-03-21 15:43:16 +01:00
|
|
|
* For instance a group with two
|
|
|
|
* nexthops will have two dependencies
|
|
|
|
* pointing to those nhg_hash_entries.
|
2019-05-14 02:10:34 +02:00
|
|
|
*
|
|
|
|
* Using a rb tree here to make lookups
|
|
|
|
* faster with ID's.
|
2019-03-21 15:43:16 +01:00
|
|
|
*/
|
2019-07-24 18:27:40 +02:00
|
|
|
struct nhg_connected_tree_head nhg_depends, nhg_dependents;
|
2019-01-24 03:32:49 +01:00
|
|
|
/*
|
|
|
|
* Is this nexthop group valid, ie all nexthops are fully resolved.
|
|
|
|
* What is fully resolved? It's a nexthop that is either self contained
|
|
|
|
* and correct( ie no recursive pointer ) or a nexthop that is recursively
|
|
|
|
* resolved and correct.
|
|
|
|
*/
|
2019-08-01 20:07:04 +02:00
|
|
|
#define NEXTHOP_GROUP_VALID (1 << 0)
|
2019-01-24 03:32:49 +01:00
|
|
|
/*
|
|
|
|
* Has this nexthop group been installed? At this point in time, this
|
|
|
|
* means that the data-plane has been told about this nexthop group
|
|
|
|
* and it's possible usage by a route entry.
|
|
|
|
*/
|
2019-08-01 20:07:04 +02:00
|
|
|
#define NEXTHOP_GROUP_INSTALLED (1 << 1)
|
2019-03-06 20:56:04 +01:00
|
|
|
/*
|
|
|
|
* Has the nexthop group been queued to be send to the FIB?
|
|
|
|
* The NEXTHOP_GROUP_VALID flag should also be set by this point.
|
|
|
|
*/
|
2019-08-01 20:07:04 +02:00
|
|
|
#define NEXTHOP_GROUP_QUEUED (1 << 2)
|
2019-05-15 00:27:40 +02:00
|
|
|
/*
|
|
|
|
* Is this a nexthop that is recursively resolved?
|
|
|
|
*/
|
2019-08-01 20:07:04 +02:00
|
|
|
#define NEXTHOP_GROUP_RECURSIVE (1 << 3)
|
|
|
|
/*
|
|
|
|
* This is a duplicate nexthop we got from the kernel, we are only tracking
|
|
|
|
* it in our ID hash table, it is unusable by our routes.
|
|
|
|
*/
|
|
|
|
#define NEXTHOP_GROUP_DUPLICATE (1 << 4)
|
2019-01-24 14:06:34 +01:00
|
|
|
};
|
|
|
|
|
2019-08-01 20:07:04 +02:00
|
|
|
/* Was this one we created, either this session or previously? */
|
|
|
|
#define ZEBRA_NHG_CREATED(NHE) ((NHE->type) == ZEBRA_ROUTE_NHG)
|
|
|
|
|
2019-05-14 03:13:02 +02:00
|
|
|
/* Abstraction for connected trees */
|
|
|
|
struct nhg_connected {
|
2019-07-24 18:27:40 +02:00
|
|
|
struct nhg_connected_tree_item tree_item;
|
2019-03-21 15:43:16 +01:00
|
|
|
struct nhg_hash_entry *nhe;
|
|
|
|
};
|
|
|
|
|
2019-07-24 18:27:40 +02:00
|
|
|
static int nhg_connected_cmp(const struct nhg_connected *con1,
|
|
|
|
const struct nhg_connected *con2)
|
|
|
|
{
|
|
|
|
return (con1->nhe->id - con2->nhe->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
DECLARE_RBTREE_UNIQ(nhg_connected_tree, struct nhg_connected, tree_item,
|
|
|
|
nhg_connected_cmp);
|
2019-03-21 15:43:16 +01:00
|
|
|
|
2019-05-15 00:03:29 +02:00
|
|
|
|
|
|
|
enum nhg_ctx_op_e {
|
|
|
|
NHG_CTX_OP_NONE = 0,
|
|
|
|
NHG_CTX_OP_NEW,
|
|
|
|
NHG_CTX_OP_DEL,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum nhg_ctx_result {
|
|
|
|
NHG_CTX_NONE = 0,
|
|
|
|
NHG_CTX_QUEUED,
|
|
|
|
NHG_CTX_SUCCESS,
|
|
|
|
NHG_CTX_FAILURE,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Context needed to queue nhg updates on the
|
|
|
|
* work queue.
|
|
|
|
*/
|
|
|
|
struct nhg_ctx {
|
|
|
|
|
|
|
|
/* Unique ID */
|
|
|
|
uint32_t id;
|
|
|
|
|
|
|
|
vrf_id_t vrf_id;
|
|
|
|
afi_t afi;
|
2019-08-01 20:07:04 +02:00
|
|
|
/*
|
|
|
|
* This should only every be ZEBRA_ROUTE_NHG unless we get a a kernel
|
|
|
|
* created nexthop not made by us.
|
|
|
|
*/
|
|
|
|
int type;
|
2019-05-15 00:03:29 +02:00
|
|
|
|
|
|
|
/* If its a group array, how many? */
|
|
|
|
uint8_t count;
|
|
|
|
|
|
|
|
/* Its either a single nexthop or an array of ID's */
|
|
|
|
union {
|
|
|
|
struct nexthop nh;
|
|
|
|
struct nh_grp grp[MULTIPATH_NUM];
|
|
|
|
} u;
|
|
|
|
|
|
|
|
enum nhg_ctx_op_e op;
|
|
|
|
enum nhg_ctx_result status;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2019-01-24 14:06:34 +01:00
|
|
|
void zebra_nhg_init(void);
|
|
|
|
void zebra_nhg_terminate(void);
|
|
|
|
|
2019-05-14 18:53:19 +02:00
|
|
|
extern void nhg_connected_free(struct nhg_connected *dep);
|
|
|
|
extern struct nhg_connected *nhg_connected_new(struct nhg_hash_entry *nhe);
|
|
|
|
|
|
|
|
/* nhg connected tree direct access functions */
|
2019-07-24 18:27:40 +02:00
|
|
|
extern void nhg_connected_tree_init(struct nhg_connected_tree_head *head);
|
|
|
|
extern void nhg_connected_tree_free(struct nhg_connected_tree_head *head);
|
|
|
|
extern bool
|
|
|
|
nhg_connected_tree_is_empty(const struct nhg_connected_tree_head *head);
|
2019-05-15 00:27:40 +02:00
|
|
|
extern struct nhg_connected *
|
2019-07-24 18:27:40 +02:00
|
|
|
nhg_connected_tree_root(struct nhg_connected_tree_head *head);
|
|
|
|
extern void nhg_connected_tree_del_nhe(struct nhg_connected_tree_head *head,
|
|
|
|
struct nhg_hash_entry *nhe);
|
|
|
|
extern void nhg_connected_tree_add_nhe(struct nhg_connected_tree_head *head,
|
|
|
|
struct nhg_hash_entry *nhe);
|
2019-05-14 18:53:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* NHE abstracted tree functions.
|
|
|
|
* Use these where possible instead of the direct ones access ones.
|
|
|
|
*/
|
2019-05-15 00:27:40 +02:00
|
|
|
|
|
|
|
|
|
|
|
extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe);
|
|
|
|
extern uint32_t zebra_nhg_get_resolved_id(uint32_t id);
|
|
|
|
|
2019-05-14 18:53:19 +02:00
|
|
|
/* Depends */
|
|
|
|
extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe);
|
2019-05-14 02:10:34 +02:00
|
|
|
extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe);
|
|
|
|
extern void zebra_nhg_depends_del(struct nhg_hash_entry *from,
|
|
|
|
struct nhg_hash_entry *depend);
|
|
|
|
extern void zebra_nhg_depends_add(struct nhg_hash_entry *to,
|
|
|
|
struct nhg_hash_entry *depend);
|
|
|
|
extern void zebra_nhg_depends_init(struct nhg_hash_entry *nhe);
|
2019-05-14 18:53:19 +02:00
|
|
|
/* Dependents */
|
|
|
|
extern unsigned int
|
|
|
|
zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe);
|
|
|
|
extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe);
|
|
|
|
extern void zebra_nhg_dependents_del(struct nhg_hash_entry *from,
|
|
|
|
struct nhg_hash_entry *dependent);
|
|
|
|
extern void zebra_nhg_dependents_add(struct nhg_hash_entry *to,
|
|
|
|
struct nhg_hash_entry *dependent);
|
|
|
|
extern void zebra_nhg_dependents_init(struct nhg_hash_entry *nhe);
|
2019-03-21 15:43:16 +01:00
|
|
|
|
|
|
|
|
2019-02-26 00:18:07 +01:00
|
|
|
extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id);
|
|
|
|
extern int zebra_nhg_insert_id(struct nhg_hash_entry *nhe);
|
|
|
|
|
2019-01-24 14:06:34 +01:00
|
|
|
extern uint32_t zebra_nhg_hash_key(const void *arg);
|
2019-02-15 19:18:48 +01:00
|
|
|
extern uint32_t zebra_nhg_id_key(const void *arg);
|
2019-01-24 14:06:34 +01:00
|
|
|
|
|
|
|
extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2);
|
2019-02-26 00:18:07 +01:00
|
|
|
extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2);
|
2019-01-24 14:06:34 +01:00
|
|
|
|
2019-05-15 00:03:29 +02:00
|
|
|
/*
|
|
|
|
* Process a context off of a queue.
|
|
|
|
* Specifically this should be from
|
|
|
|
* the rib meta queue.
|
|
|
|
*/
|
|
|
|
extern int nhg_ctx_process(struct nhg_ctx *ctx);
|
2019-03-21 15:47:19 +01:00
|
|
|
|
2019-05-15 00:03:29 +02:00
|
|
|
/* Find via kernel nh creation */
|
|
|
|
extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh,
|
|
|
|
struct nh_grp *grp, uint8_t count,
|
2019-08-01 20:07:04 +02:00
|
|
|
vrf_id_t vrf_id, afi_t afi, int type,
|
|
|
|
int startup);
|
2019-05-15 00:03:29 +02:00
|
|
|
|
|
|
|
/* Find via route creation */
|
2019-07-02 07:16:48 +02:00
|
|
|
extern struct nhg_hash_entry *
|
|
|
|
zebra_nhg_rib_find(uint32_t id, struct nexthop_group *nhg, afi_t rt_afi);
|
2019-03-29 15:51:07 +01:00
|
|
|
|
2019-05-14 02:10:34 +02:00
|
|
|
|
2019-03-22 18:07:22 +01:00
|
|
|
void zebra_nhg_free_members(struct nhg_hash_entry *nhe);
|
2019-02-26 00:18:07 +01:00
|
|
|
void zebra_nhg_free(void *arg);
|
|
|
|
void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe);
|
2019-03-29 23:14:20 +01:00
|
|
|
void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe);
|
2019-05-15 00:03:29 +02:00
|
|
|
|
2019-05-14 18:53:19 +02:00
|
|
|
void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe);
|
|
|
|
void zebra_nhg_set_if(struct nhg_hash_entry *nhe, struct interface *ifp);
|
2019-02-25 23:59:28 +01:00
|
|
|
|
|
|
|
extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);
|
2019-03-06 20:58:57 +01:00
|
|
|
|
2019-05-15 01:26:20 +02:00
|
|
|
extern int zebra_nhg_re_update_ref(struct route_entry *re,
|
|
|
|
struct nhg_hash_entry *nhe);
|
|
|
|
|
2019-07-25 19:27:59 +02:00
|
|
|
extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
|
|
|
|
int size);
|
2019-05-15 00:27:40 +02:00
|
|
|
|
2019-03-06 20:58:57 +01:00
|
|
|
void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
|
2019-03-08 00:11:57 +01:00
|
|
|
void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
|
|
|
|
|
2019-08-01 20:07:04 +02:00
|
|
|
void zebra_nhg_cleanup_tables(struct hash *hash);
|
2019-03-08 00:15:30 +01:00
|
|
|
|
2019-05-14 02:10:34 +02:00
|
|
|
/* Forward ref of dplane update context type */
|
|
|
|
struct zebra_dplane_ctx;
|
2019-03-08 00:15:30 +01:00
|
|
|
void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx);
|
2019-08-01 20:07:04 +02:00
|
|
|
|
|
|
|
void zebra_nhg_sweep_table(struct hash *hash);
|
2019-05-13 21:46:05 +02:00
|
|
|
#endif
|