summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_api.h
blob: 6160a0f1fa03facf3170ab66d16f7a2e72470ced (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
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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * API message handling module for OSPF daemon and client.
 * Copyright (C) 2001, 2002 Ralph Keller
 * Copyright (c) 2022, LabN Consulting, L.L.C.
 */


/* This file is used both by the OSPFd and client applications to
   define message formats used for communication. */

#ifndef _OSPF_API_H
#define _OSPF_API_H

#include <zebra.h>
#include "ospf_lsa.h"

#define OSPF_API_VERSION           1

/* MTYPE definition is not reflected to "memory.h". */
#define MTYPE_OSPF_API_MSG      MTYPE_TMP
#define MTYPE_OSPF_API_FIFO     MTYPE_TMP

/* -----------------------------------------------------------
 * Generic messages
 * -----------------------------------------------------------
 */

/* Message header structure, fields are in network byte order and
   aligned to four octets. */
struct apimsghdr {
	uint8_t version; /* OSPF API protocol version */
	uint8_t msgtype; /* Type of message */
	uint16_t msglen; /* Length of message w/o header */
	uint32_t msgseq; /* Sequence number */
};

/* Message representation with header and body */
struct msg {
	struct msg *next; /* to link into fifo */

	/* Message header */
	struct apimsghdr hdr;

	/* Message body */
	struct stream *s;
};

/* Prototypes for generic messages. */
extern struct msg *msg_new(uint8_t msgtype, void *msgbody, uint32_t seqnum,
			   uint16_t msglen);
extern struct msg *msg_dup(struct msg *msg);
extern void msg_print(struct msg *msg); /* XXX debug only */
extern void msg_free(struct msg *msg);
struct msg *msg_read(int fd);
extern int msg_write(int fd, struct msg *msg);

/* For requests, the message sequence number is between MIN_SEQ and
   MAX_SEQ. For notifications, the sequence number is 0. */

#define MIN_SEQ          1
#define MAX_SEQ 2147483647

extern void msg_set_seq(struct msg *msg, uint32_t seqnr);
extern uint32_t msg_get_seq(struct msg *msg);

/* -----------------------------------------------------------
 * Message fifo queues
 * -----------------------------------------------------------
 */

/* Message queue structure. */
struct msg_fifo {
	unsigned long count;

	struct msg *head;
	struct msg *tail;
};

/* Prototype for message fifo queues. */
extern struct msg_fifo *msg_fifo_new(void);
extern void msg_fifo_push(struct msg_fifo *, struct msg *msg);
extern struct msg *msg_fifo_pop(struct msg_fifo *fifo);
extern struct msg *msg_fifo_head(struct msg_fifo *fifo);
extern void msg_fifo_flush(struct msg_fifo *fifo);
extern void msg_fifo_free(struct msg_fifo *fifo);

/* -----------------------------------------------------------
 * Specific message type and format definitions
 * -----------------------------------------------------------
 */

/* Messages to OSPF daemon. */
#define MSG_REGISTER_OPAQUETYPE   1
#define MSG_UNREGISTER_OPAQUETYPE 2
#define MSG_REGISTER_EVENT        3
#define MSG_SYNC_LSDB             4
#define MSG_ORIGINATE_REQUEST     5
#define MSG_DELETE_REQUEST        6
#define MSG_SYNC_REACHABLE        7
#define MSG_SYNC_ISM              8
#define MSG_SYNC_NSM              9
#define MSG_SYNC_ROUTER_ID        19

/* Messages from OSPF daemon. */
#define MSG_REPLY                10
#define MSG_READY_NOTIFY         11
#define MSG_LSA_UPDATE_NOTIFY    12
#define MSG_LSA_DELETE_NOTIFY    13
#define MSG_NEW_IF               14
#define MSG_DEL_IF               15
#define MSG_ISM_CHANGE           16
#define MSG_NSM_CHANGE           17
#define MSG_REACHABLE_CHANGE     18
#define MSG_ROUTER_ID_CHANGE     20

struct msg_register_opaque_type {
	uint8_t lsatype;
	uint8_t opaquetype;
	uint8_t pad[2]; /* padding */
};

struct msg_unregister_opaque_type {
	uint8_t lsatype;
	uint8_t opaquetype;
	uint8_t pad[2]; /* padding */
};

/* Power2 is needed to convert LSA types into bit positions,
 * see typemask below. Type definition starts at 1, so
 * Power2[0] is not used. */


static const uint16_t Power2[] = {
	0,	 (1 << 0),  (1 << 1),  (1 << 2),  (1 << 3), (1 << 4),
	(1 << 5),  (1 << 6),  (1 << 7),  (1 << 8),  (1 << 9), (1 << 10),
	(1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15)};

struct lsa_filter_type {
	uint16_t typemask; /* bitmask for selecting LSA types (1..16) */
	uint8_t origin;    /* selects according to origin. */
#define NON_SELF_ORIGINATED	0
#define	SELF_ORIGINATED  (OSPF_LSA_SELF)
#define	ANY_ORIGIN 2

	uint8_t num_areas; /* number of areas in the filter. */
			   /* areas, if any, go here. */
};

struct msg_register_event {
	struct lsa_filter_type filter;
};

struct msg_sync_lsdb {
	struct lsa_filter_type filter;
};

struct msg_originate_request {
	/* Used for LSA type 9 otherwise ignored */
	struct in_addr ifaddr;

	/* Used for LSA type 10 otherwise ignored */
	struct in_addr area_id;

	/* LSA header and LSA-specific part */
	struct lsa_header data;
};


/* OSPF API MSG Delete Flag. */
#define OSPF_API_DEL_ZERO_LEN_LSA 0x01 /* send withdrawal with no LSA data */

#define IS_DEL_ZERO_LEN_LSA(x) ((x)->flags & OSPF_API_DEL_ZERO_LEN_LSA)

struct msg_delete_request {
	struct in_addr addr; /* intf IP for link local, area for type 10,
				"0.0.0.0" for AS-external */
	uint8_t lsa_type;
	uint8_t opaque_type;
	uint8_t pad;   /* padding */
	uint8_t flags; /* delete flags */
	uint32_t opaque_id;
};

struct msg_reply {
	signed char errcode;
#define OSPF_API_OK                         0
#define OSPF_API_NOSUCHINTERFACE          (-1)
#define OSPF_API_NOSUCHAREA               (-2)
#define OSPF_API_NOSUCHLSA                (-3)
#define OSPF_API_ILLEGALLSATYPE           (-4)
#define OSPF_API_OPAQUETYPEINUSE          (-5)
#define OSPF_API_OPAQUETYPENOTREGISTERED  (-6)
#define OSPF_API_NOTREADY                 (-7)
#define OSPF_API_NOMEMORY                 (-8)
#define OSPF_API_ERROR                    (-9)
#define OSPF_API_UNDEF                   (-10)
	uint8_t pad[3]; /* padding to four byte alignment */
};

/* Message to tell client application that it ospf daemon is
 * ready to accept opaque LSAs for a given interface or area. */

struct msg_ready_notify {
	uint8_t lsa_type;
	uint8_t opaque_type;
	uint8_t pad[2];      /* padding */
	struct in_addr addr; /* interface address or area address */
};

/* These messages have a dynamic length depending on the embodied LSA.
   They are aligned to four octets. msg_lsa_change_notify is used for
   both LSA update and LSAs delete. */

struct msg_lsa_change_notify {
	/* Used for LSA type 9 otherwise ignored */
	struct in_addr ifaddr;
	/* Area ID. Not valid for AS-External and Opaque11 LSAs. */
	struct in_addr area_id;
	uint8_t is_self_originated; /* 1 if self originated. */
	uint8_t pad[3];
	struct lsa_header data;
};

struct msg_new_if {
	struct in_addr ifaddr;  /* interface IP address */
	struct in_addr area_id; /* area this interface belongs to */
};

struct msg_del_if {
	struct in_addr ifaddr; /* interface IP address */
};

struct msg_ism_change {
	struct in_addr ifaddr;  /* interface IP address */
	struct in_addr area_id; /* area this interface belongs to */
	uint8_t status;		/* interface status (up/down) */
	uint8_t pad[3];		/* not used */
};

struct msg_nsm_change {
	struct in_addr ifaddr;    /* attached interface */
	struct in_addr nbraddr;   /* Neighbor interface address */
	struct in_addr router_id; /* Router ID of neighbor */
	uint8_t status;		  /* NSM status */
	uint8_t pad[3];
};

struct msg_reachable_change {
	uint16_t nadd;
	uint16_t nremove;
	struct in_addr router_ids[]; /* add followed by remove */
};

struct msg_router_id_change {
	struct in_addr router_id; /* this systems router id */
};

/* We make use of a union to define a structure that covers all
   possible API messages. This allows us to find out how much memory
   needs to be reserved for the largest API message. */
struct apimsg {
	struct apimsghdr hdr;
	union {
		struct msg_register_opaque_type register_opaque_type;
		struct msg_register_event register_event;
		struct msg_sync_lsdb sync_lsdb;
		struct msg_originate_request originate_request;
		struct msg_delete_request delete_request;
		struct msg_reply reply;
		struct msg_ready_notify ready_notify;
		struct msg_new_if new_if;
		struct msg_del_if del_if;
		struct msg_ism_change ism_change;
		struct msg_nsm_change nsm_change;
		struct msg_lsa_change_notify lsa_change_notify;
		struct msg_reachable_change reachable_change;
		struct msg_router_id_change router_id_change;
	} u;
};

#define OSPF_API_MAX_MSG_SIZE (sizeof(struct apimsg) + OSPF_MAX_PACKET_SIZE)

/* -----------------------------------------------------------
 * Prototypes for specific messages
 * -----------------------------------------------------------
 */

/* For debugging only. */
extern void api_opaque_lsa_print(struct ospf_lsa *lsa);

/* Messages sent by client */
extern struct msg *new_msg_register_opaque_type(uint32_t seqnum, uint8_t ltype,
						uint8_t otype);
extern struct msg *new_msg_register_event(uint32_t seqnum,
					  struct lsa_filter_type *filter);
extern struct msg *new_msg_sync_lsdb(uint32_t seqnum,
				     struct lsa_filter_type *filter);
extern struct msg *new_msg_originate_request(uint32_t seqnum,
					     struct in_addr ifaddr,
					     struct in_addr area_id,
					     struct lsa_header *data);
extern struct msg *new_msg_delete_request(uint32_t seqnum, struct in_addr addr,
					  uint8_t lsa_type, uint8_t opaque_type,
					  uint32_t opaque_id, uint8_t flags);

/* Messages sent by OSPF daemon */
extern struct msg *new_msg_reply(uint32_t seqnum, uint8_t rc);

extern struct msg *new_msg_ready_notify(uint32_t seqnr, uint8_t lsa_type,
					uint8_t opaque_type,
					struct in_addr addr);

extern struct msg *new_msg_new_if(uint32_t seqnr, struct in_addr ifaddr,
				  struct in_addr area);

extern struct msg *new_msg_del_if(uint32_t seqnr, struct in_addr ifaddr);

extern struct msg *new_msg_ism_change(uint32_t seqnr, struct in_addr ifaddr,
				      struct in_addr area, uint8_t status);

extern struct msg *new_msg_nsm_change(uint32_t seqnr, struct in_addr ifaddr,
				      struct in_addr nbraddr,
				      struct in_addr router_id, uint8_t status);

/* msgtype is MSG_LSA_UPDATE_NOTIFY or MSG_LSA_DELETE_NOTIFY */
extern struct msg *new_msg_lsa_change_notify(uint8_t msgtype, uint32_t seqnum,
					     struct in_addr ifaddr,
					     struct in_addr area_id,
					     uint8_t is_self_originated,
					     struct lsa_header *data);

extern struct msg *new_msg_reachable_change(uint32_t seqnum, uint16_t nadd,
					    struct in_addr *add,
					    uint16_t nremove,
					    struct in_addr *remove);

extern struct msg *new_msg_router_id_change(uint32_t seqnr,
					    struct in_addr router_id);
/* string printing functions */
extern const char *ospf_api_errname(int errcode);
extern const char *ospf_api_typename(int msgtype);

#endif /* _OSPF_API_H */