summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_spf.h
blob: c2fd5d9ef1003b09080560a0267c45ab3bd7afe1 (plain)
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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2003 Yasuhiro Ohara
 */

#ifndef OSPF6_SPF_H
#define OSPF6_SPF_H

#include "typesafe.h"
#include "ospf6_top.h"
#include "lib/json.h"

/* Debug option */
extern unsigned char conf_debug_ospf6_spf;
#define OSPF6_DEBUG_SPF_PROCESS   0x01
#define OSPF6_DEBUG_SPF_TIME      0x02
#define OSPF6_DEBUG_SPF_DATABASE  0x04
#define OSPF6_DEBUG_SPF_ON(level) (conf_debug_ospf6_spf |= (level))
#define OSPF6_DEBUG_SPF_OFF(level) (conf_debug_ospf6_spf &= ~(level))
#define IS_OSPF6_DEBUG_SPF(level)                                              \
	(conf_debug_ospf6_spf & OSPF6_DEBUG_SPF_##level)

#define OSPF6_ASE_CALC_INTERVAL 1

PREDECL_SKIPLIST_NONUNIQ(vertex_pqueue);
/* Transit Vertex */
struct ospf6_vertex {
	/* type of this vertex */
	uint8_t type;

	/* Vertex Identifier */
	struct prefix vertex_id;

	struct vertex_pqueue_item pqi;

	/* Identifier String */
	char name[128];

	/* Associated Area */
	struct ospf6_area *area;

	/* Associated LSA */
	struct ospf6_lsa *lsa;

	/* Distance from Root (i.e. Cost) */
	uint32_t cost;

	/* Router hops to this node */
	uint8_t hops;

	/* capability bits */
	uint8_t capability;

	/* Optional capabilities */
	uint8_t options[3];

	/* For tree display */
	struct ospf6_vertex *parent;
	struct list *child_list;

	/* nexthops to this node */
	struct list *nh_list;
	uint32_t link_id;
};

#define OSPF6_VERTEX_TYPE_ROUTER  0x01
#define OSPF6_VERTEX_TYPE_NETWORK 0x02
#define VERTEX_IS_TYPE(t, v) ((v)->type == OSPF6_VERTEX_TYPE_##t ? 1 : 0)

/* What triggered the SPF? */
#define OSPF6_SPF_FLAGS_ROUTER_LSA_ADDED         (1 << 0)
#define OSPF6_SPF_FLAGS_ROUTER_LSA_REMOVED       (1 << 1)
#define OSPF6_SPF_FLAGS_NETWORK_LSA_ADDED        (1 << 2)
#define OSPF6_SPF_FLAGS_NETWORK_LSA_REMOVED      (1 << 3)
#define OSPF6_SPF_FLAGS_LINK_LSA_ADDED           (1 << 4)
#define OSPF6_SPF_FLAGS_LINK_LSA_REMOVED         (1 << 5)
#define OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED    (1 << 6)
#define OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED   (1 << 7)
#define OSPF6_SPF_FLAGS_CONFIG_CHANGE            (1 << 8)
#define OSPF6_SPF_FLAGS_ASBR_STATUS_CHANGE       (1 << 9)
#define OSPF6_SPF_FLAGS_GR_FINISH                (1 << 10)

static inline void ospf6_set_spf_reason(struct ospf6 *ospf, unsigned int reason)
{
	ospf->spf_reason |= reason;
}

static inline void ospf6_reset_spf_reason(struct ospf6 *ospf)
{
	ospf->spf_reason = 0;
}

static inline unsigned int ospf6_lsadd_to_spf_reason(struct ospf6_lsa *lsa)
{
	unsigned int reason = 0;

	switch (ntohs(lsa->header->type)) {
	case OSPF6_LSTYPE_ROUTER:
		reason = OSPF6_SPF_FLAGS_ROUTER_LSA_ADDED;
		break;
	case OSPF6_LSTYPE_NETWORK:
		reason = OSPF6_SPF_FLAGS_NETWORK_LSA_ADDED;
		break;
	case OSPF6_LSTYPE_LINK:
		reason = OSPF6_SPF_FLAGS_LINK_LSA_ADDED;
		break;
	default:
		break;
	}
	return (reason);
}

static inline unsigned int ospf6_lsremove_to_spf_reason(struct ospf6_lsa *lsa)
{
	unsigned int reason = 0;

	switch (ntohs(lsa->header->type)) {
	case OSPF6_LSTYPE_ROUTER:
		reason = OSPF6_SPF_FLAGS_ROUTER_LSA_REMOVED;
		break;
	case OSPF6_LSTYPE_NETWORK:
		reason = OSPF6_SPF_FLAGS_NETWORK_LSA_REMOVED;
		break;
	case OSPF6_LSTYPE_LINK:
		reason = OSPF6_SPF_FLAGS_LINK_LSA_REMOVED;
		break;
	default:
		break;
	}
	return (reason);
}

extern void ospf6_spf_table_finish(struct ospf6_route_table *result_table);
extern void ospf6_spf_calculation(uint32_t router_id,
				  struct ospf6_route_table *result_table,
				  struct ospf6_area *oa);
extern void ospf6_spf_schedule(struct ospf6 *ospf, unsigned int reason);

extern void ospf6_spf_display_subtree(struct vty *vty, const char *prefix,
				      int rest, struct ospf6_vertex *v,
				      json_object *json_obj, bool use_json);

extern void ospf6_spf_config_write(struct vty *vty, struct ospf6 *ospf6);
extern int config_write_ospf6_debug_spf(struct vty *vty);
extern void install_element_ospf6_debug_spf(void);
extern void ospf6_spf_init(void);
extern void ospf6_spf_reason_string(unsigned int reason, char *buf, int size);
extern struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area,
							struct ospf6_lsdb *lsdb,
							uint32_t adv_router);
extern void ospf6_remove_temp_router_lsa(struct ospf6_area *area);
extern void ospf6_ase_calculate_timer_add(struct ospf6 *ospf6);
extern int ospf6_ase_calculate_route(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
				     struct ospf6_area *area);
extern bool
ospf6_merge_parents_nh_to_child(struct ospf6_vertex *v,
				struct ospf6_route *route,
				struct ospf6_route_table *result_table);
#endif /* OSPF6_SPF_H */