summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_opaque.h
blob: 54651f8f58a6c7f97f6fe4aca959a36e89ce139f (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
160
161
162
163
164
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * This is an implementation of rfc2370.
 * Copyright (C) 2001 KDD R&D Laboratories, Inc.
 * http://www.kddlabs.co.jp/
 */

#ifndef _ZEBRA_OSPF_OPAQUE_H
#define _ZEBRA_OSPF_OPAQUE_H

#include "vty.h"
#include <lib/json.h>

#define IS_OPAQUE_LSA(type)                                                    \
	((type) == OSPF_OPAQUE_LINK_LSA || (type) == OSPF_OPAQUE_AREA_LSA      \
	 || (type) == OSPF_OPAQUE_AS_LSA)

/*
 * Opaque LSA's link state ID is redefined as follows.
 *
 *        24       16        8        0
 * +--------+--------+--------+--------+
 * |tttttttt|........|........|........|
 * +--------+--------+--------+--------+
 * |<-Type->|<------- Opaque ID ------>|
 */
#define LSID_OPAQUE_TYPE_MASK	0xff000000	/*  8 bits */
#define LSID_OPAQUE_ID_MASK	0x00ffffff	/* 24 bits */

#define GET_OPAQUE_TYPE(lsid) (((uint32_t)(lsid)&LSID_OPAQUE_TYPE_MASK) >> 24)

#define GET_OPAQUE_ID(lsid) ((uint32_t)(lsid)&LSID_OPAQUE_ID_MASK)

#define SET_OPAQUE_LSID(type, id)                                              \
	((((unsigned)(type) << 24) & LSID_OPAQUE_TYPE_MASK)                    \
	 | ((id)&LSID_OPAQUE_ID_MASK))

/*
 * Opaque LSA types will be assigned by IANA.
 * <http://www.iana.org/assignments/ospf-opaque-types>
 */
#define OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA		1
#define OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC	2
#define OPAQUE_TYPE_GRACE_LSA				3
#define OPAQUE_TYPE_L1VPN_LSA                          5
#define OPAQUE_TYPE_ROUTER_INFORMATION_LSA             4
#define OPAQUE_TYPE_INTER_AS_LSA                       6
#define OPAQUE_TYPE_EXTENDED_PREFIX_LSA                7
#define OPAQUE_TYPE_EXTENDED_LINK_LSA                  8
#define OPAQUE_TYPE_MAX                                8

/* Following types are proposed in internet-draft documents. */
#define OPAQUE_TYPE_8021_QOSPF				129
#define OPAQUE_TYPE_SECONDARY_NEIGHBOR_DISCOVERY	224
#define OPAQUE_TYPE_FLOODGATE                           225

/* Ugly hack to make use of an unallocated value for wildcard matching! */
#define OPAQUE_TYPE_WILDCARD				0

#define OPAQUE_TYPE_RANGE_UNASSIGNED(type)                                     \
	(OPAQUE_TYPE_MAX <= (type) && (type) <= 127)

#define OPAQUE_TYPE_RANGE_RESERVED(type) (127 < (type) && (type) <= 255)

#define OSPF_OPAQUE_LSA_MIN_SIZE 0 /* RFC5250 imposes no minimum */

#define VALID_OPAQUE_INFO_LEN(lsahdr)                                          \
	((ntohs((lsahdr)->length) >= sizeof(struct lsa_header))                \
	 && ((ntohs((lsahdr)->length) < OSPF_MAX_LSA_SIZE))                    \
	 && ((ntohs((lsahdr)->length) % sizeof(uint32_t)) == 0))

/*
 * Following section defines generic TLV (type, length, value) macros,
 * used for various LSA opaque usage e.g. Traffic Engineering.
 */
struct tlv_header {
	uint16_t type;   /* Type of Value */
	uint16_t length; /* Length of Value portion only, in bytes */
};

#define TLV_HDR_SIZE	(sizeof(struct tlv_header))

#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t)))

#define TLV_SIZE(tlvh)	(uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))

#define TLV_HDR_TOP(lsah)                                                      \
	(struct tlv_header *)((char *)(lsah) + OSPF_LSA_HEADER_SIZE)

#define TLV_HDR_NEXT(tlvh)                                                     \
	(struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))

#define TLV_HDR_SUBTLV(tlvh)                                                   \
	(struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE)

#define TLV_DATA(tlvh)	(void *)((char *)(tlvh) + TLV_HDR_SIZE)

#define TLV_TYPE(tlvh)	tlvh.header.type
#define TLV_LEN(tlvh)	tlvh.header.length
#define TLV_HDR(tlvh)	tlvh.header

/* Following declaration concerns the Opaque LSA management */
enum lsa_opcode { REORIGINATE_THIS_LSA, REFRESH_THIS_LSA, FLUSH_THIS_LSA };

/* Prototypes. */

extern void ospf_opaque_init(void);
extern void ospf_opaque_term(void);
extern void ospf_opaque_finish(void);
extern int ospf_opaque_type9_lsa_init(struct ospf_interface *oi);
extern void ospf_opaque_type9_lsa_term(struct ospf_interface *oi);
extern void ospf_opaque_type9_lsa_if_cleanup(struct ospf_interface *oi);
extern int ospf_opaque_type10_lsa_init(struct ospf_area *area);
extern void ospf_opaque_type10_lsa_term(struct ospf_area *area);
extern int ospf_opaque_type11_lsa_init(struct ospf *ospf);
extern void ospf_opaque_type11_lsa_term(struct ospf *ospf);

extern int ospf_register_opaque_functab(
	uint8_t lsa_type, uint8_t opaque_type,
	int (*new_if_hook)(struct interface *ifp),
	int (*del_if_hook)(struct interface *ifp),
	void (*ism_change_hook)(struct ospf_interface *oi, int old_status),
	void (*nsm_change_hook)(struct ospf_neighbor *nbr, int old_status),
	void (*config_write_router)(struct vty *vty),
	void (*config_write_if)(struct vty *vty, struct interface *ifp),
	void (*config_write_debug)(struct vty *vty),
	void (*show_opaque_info)(struct vty *vty, struct json_object *json,
				 struct ospf_lsa *lsa),
	int (*lsa_originator)(void *arg),
	struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa),
	int (*new_lsa_hook)(struct ospf_lsa *lsa),
	int (*del_lsa_hook)(struct ospf_lsa *lsa));
extern void ospf_delete_opaque_functab(uint8_t lsa_type, uint8_t opaque_type);

extern int ospf_opaque_new_if(struct interface *ifp);
extern int ospf_opaque_del_if(struct interface *ifp);
extern void ospf_opaque_ism_change(struct ospf_interface *oi, int old_status);
extern void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_status);
extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *ospf);
extern void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp);
extern void ospf_opaque_config_write_debug(struct vty *vty);
extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
				    json_object *json);
extern void ospf_opaque_lsa_dump(struct stream *s, uint16_t length);

extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi,
					       int *init_delay);
extern struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa,
						int rt_recalc);
extern struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa);

extern void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
						 uint8_t lsa_type,
						 uint8_t opaque_type);
extern void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa);
extern void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa);

extern void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr,
						     struct ospf_lsa *lsa);
extern struct ospf *oi_to_top(struct ospf_interface *oi);

extern int ospf_opaque_is_owned(struct ospf_lsa *lsa);

#endif /* _ZEBRA_OSPF_OPAQUE_H */