]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2d33f157 | 2 | /* |
3 | * API message handling module for OSPF daemon and client. | |
4 | * Copyright (C) 2001, 2002 Ralph Keller | |
44038c7a | 5 | * Copyright (c) 2022, LabN Consulting, L.L.C. |
2d33f157 | 6 | */ |
7 | ||
8 | ||
9 | /* This file is used both by the OSPFd and client applications to | |
10 | define message formats used for communication. */ | |
11 | ||
12 | #ifndef _OSPF_API_H | |
13 | #define _OSPF_API_H | |
14 | ||
149491af CH |
15 | #include <zebra.h> |
16 | #include "ospf_lsa.h" | |
17 | ||
2d33f157 | 18 | #define OSPF_API_VERSION 1 |
19 | ||
20 | /* MTYPE definition is not reflected to "memory.h". */ | |
21 | #define MTYPE_OSPF_API_MSG MTYPE_TMP | |
22 | #define MTYPE_OSPF_API_FIFO MTYPE_TMP | |
23 | ||
24 | /* Default API server port to accept connection request from client-side. */ | |
25 | /* This value could be overridden by "ospfapi" entry in "/etc/services". */ | |
26 | #define OSPF_API_SYNC_PORT 2607 | |
27 | ||
28 | /* ----------------------------------------------------------- | |
d62a17ae | 29 | * Generic messages |
2d33f157 | 30 | * ----------------------------------------------------------- |
31 | */ | |
32 | ||
33 | /* Message header structure, fields are in network byte order and | |
34 | aligned to four octets. */ | |
d62a17ae | 35 | struct apimsghdr { |
d7c0a89a QY |
36 | uint8_t version; /* OSPF API protocol version */ |
37 | uint8_t msgtype; /* Type of message */ | |
38 | uint16_t msglen; /* Length of message w/o header */ | |
39 | uint32_t msgseq; /* Sequence number */ | |
2d33f157 | 40 | }; |
41 | ||
42 | /* Message representation with header and body */ | |
d62a17ae | 43 | struct msg { |
44 | struct msg *next; /* to link into fifo */ | |
2d33f157 | 45 | |
d62a17ae | 46 | /* Message header */ |
47 | struct apimsghdr hdr; | |
2d33f157 | 48 | |
d62a17ae | 49 | /* Message body */ |
50 | struct stream *s; | |
2d33f157 | 51 | }; |
52 | ||
53 | /* Prototypes for generic messages. */ | |
d7c0a89a QY |
54 | extern struct msg *msg_new(uint8_t msgtype, void *msgbody, uint32_t seqnum, |
55 | uint16_t msglen); | |
d62a17ae | 56 | extern struct msg *msg_dup(struct msg *msg); |
57 | extern void msg_print(struct msg *msg); /* XXX debug only */ | |
58 | extern void msg_free(struct msg *msg); | |
59 | struct msg *msg_read(int fd); | |
60 | extern int msg_write(int fd, struct msg *msg); | |
2d33f157 | 61 | |
62 | /* For requests, the message sequence number is between MIN_SEQ and | |
63 | MAX_SEQ. For notifications, the sequence number is 0. */ | |
64 | ||
65 | #define MIN_SEQ 1 | |
66 | #define MAX_SEQ 2147483647 | |
67 | ||
d7c0a89a QY |
68 | extern void msg_set_seq(struct msg *msg, uint32_t seqnr); |
69 | extern uint32_t msg_get_seq(struct msg *msg); | |
2d33f157 | 70 | |
71 | /* ----------------------------------------------------------- | |
72 | * Message fifo queues | |
73 | * ----------------------------------------------------------- | |
74 | */ | |
75 | ||
76 | /* Message queue structure. */ | |
d62a17ae | 77 | struct msg_fifo { |
78 | unsigned long count; | |
2d33f157 | 79 | |
d62a17ae | 80 | struct msg *head; |
81 | struct msg *tail; | |
2d33f157 | 82 | }; |
83 | ||
84 | /* Prototype for message fifo queues. */ | |
d62a17ae | 85 | extern struct msg_fifo *msg_fifo_new(void); |
86 | extern void msg_fifo_push(struct msg_fifo *, struct msg *msg); | |
87 | extern struct msg *msg_fifo_pop(struct msg_fifo *fifo); | |
88 | extern struct msg *msg_fifo_head(struct msg_fifo *fifo); | |
89 | extern void msg_fifo_flush(struct msg_fifo *fifo); | |
90 | extern void msg_fifo_free(struct msg_fifo *fifo); | |
2d33f157 | 91 | |
92 | /* ----------------------------------------------------------- | |
93 | * Specific message type and format definitions | |
94 | * ----------------------------------------------------------- | |
95 | */ | |
96 | ||
97 | /* Messages to OSPF daemon. */ | |
98 | #define MSG_REGISTER_OPAQUETYPE 1 | |
99 | #define MSG_UNREGISTER_OPAQUETYPE 2 | |
100 | #define MSG_REGISTER_EVENT 3 | |
101 | #define MSG_SYNC_LSDB 4 | |
102 | #define MSG_ORIGINATE_REQUEST 5 | |
103 | #define MSG_DELETE_REQUEST 6 | |
149491af | 104 | #define MSG_SYNC_REACHABLE 7 |
97355a6d CH |
105 | #define MSG_SYNC_ISM 8 |
106 | #define MSG_SYNC_NSM 9 | |
44038c7a | 107 | #define MSG_SYNC_ROUTER_ID 19 |
2d33f157 | 108 | |
109 | /* Messages from OSPF daemon. */ | |
110 | #define MSG_REPLY 10 | |
111 | #define MSG_READY_NOTIFY 11 | |
112 | #define MSG_LSA_UPDATE_NOTIFY 12 | |
113 | #define MSG_LSA_DELETE_NOTIFY 13 | |
114 | #define MSG_NEW_IF 14 | |
115 | #define MSG_DEL_IF 15 | |
116 | #define MSG_ISM_CHANGE 16 | |
117 | #define MSG_NSM_CHANGE 17 | |
149491af | 118 | #define MSG_REACHABLE_CHANGE 18 |
44038c7a | 119 | #define MSG_ROUTER_ID_CHANGE 20 |
2d33f157 | 120 | |
d62a17ae | 121 | struct msg_register_opaque_type { |
d7c0a89a QY |
122 | uint8_t lsatype; |
123 | uint8_t opaquetype; | |
124 | uint8_t pad[2]; /* padding */ | |
2d33f157 | 125 | }; |
126 | ||
d62a17ae | 127 | struct msg_unregister_opaque_type { |
d7c0a89a QY |
128 | uint8_t lsatype; |
129 | uint8_t opaquetype; | |
130 | uint8_t pad[2]; /* padding */ | |
2d33f157 | 131 | }; |
132 | ||
133 | /* Power2 is needed to convert LSA types into bit positions, | |
134 | * see typemask below. Type definition starts at 1, so | |
135 | * Power2[0] is not used. */ | |
136 | ||
137 | ||
d7c0a89a | 138 | static const uint16_t Power2[] = { |
d62a17ae | 139 | 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), |
140 | (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), | |
141 | (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15)}; | |
2d33f157 | 142 | |
d62a17ae | 143 | struct lsa_filter_type { |
d7c0a89a QY |
144 | uint16_t typemask; /* bitmask for selecting LSA types (1..16) */ |
145 | uint8_t origin; /* selects according to origin. */ | |
2d33f157 | 146 | #define NON_SELF_ORIGINATED 0 |
147 | #define SELF_ORIGINATED (OSPF_LSA_SELF) | |
148 | #define ANY_ORIGIN 2 | |
149 | ||
d7c0a89a QY |
150 | uint8_t num_areas; /* number of areas in the filter. */ |
151 | /* areas, if any, go here. */ | |
2d33f157 | 152 | }; |
153 | ||
d62a17ae | 154 | struct msg_register_event { |
155 | struct lsa_filter_type filter; | |
2d33f157 | 156 | }; |
157 | ||
d62a17ae | 158 | struct msg_sync_lsdb { |
159 | struct lsa_filter_type filter; | |
2d33f157 | 160 | }; |
161 | ||
d62a17ae | 162 | struct msg_originate_request { |
163 | /* Used for LSA type 9 otherwise ignored */ | |
164 | struct in_addr ifaddr; | |
2d33f157 | 165 | |
d62a17ae | 166 | /* Used for LSA type 10 otherwise ignored */ |
167 | struct in_addr area_id; | |
2d33f157 | 168 | |
d62a17ae | 169 | /* LSA header and LSA-specific part */ |
170 | struct lsa_header data; | |
2d33f157 | 171 | }; |
172 | ||
2f30cb25 LB |
173 | |
174 | /* OSPF API MSG Delete Flag. */ | |
175 | #define OSPF_API_DEL_ZERO_LEN_LSA 0x01 /* send withdrawal with no LSA data */ | |
176 | ||
177 | #define IS_DEL_ZERO_LEN_LSA(x) ((x)->flags & OSPF_API_DEL_ZERO_LEN_LSA) | |
178 | ||
d62a17ae | 179 | struct msg_delete_request { |
2f30cb25 LB |
180 | struct in_addr addr; /* intf IP for link local, area for type 10, |
181 | "0.0.0.0" for AS-external */ | |
d7c0a89a QY |
182 | uint8_t lsa_type; |
183 | uint8_t opaque_type; | |
2f30cb25 LB |
184 | uint8_t pad; /* padding */ |
185 | uint8_t flags; /* delete flags */ | |
d7c0a89a | 186 | uint32_t opaque_id; |
2d33f157 | 187 | }; |
188 | ||
d62a17ae | 189 | struct msg_reply { |
190 | signed char errcode; | |
2d33f157 | 191 | #define OSPF_API_OK 0 |
192 | #define OSPF_API_NOSUCHINTERFACE (-1) | |
193 | #define OSPF_API_NOSUCHAREA (-2) | |
194 | #define OSPF_API_NOSUCHLSA (-3) | |
195 | #define OSPF_API_ILLEGALLSATYPE (-4) | |
196 | #define OSPF_API_OPAQUETYPEINUSE (-5) | |
197 | #define OSPF_API_OPAQUETYPENOTREGISTERED (-6) | |
198 | #define OSPF_API_NOTREADY (-7) | |
199 | #define OSPF_API_NOMEMORY (-8) | |
200 | #define OSPF_API_ERROR (-9) | |
201 | #define OSPF_API_UNDEF (-10) | |
d7c0a89a | 202 | uint8_t pad[3]; /* padding to four byte alignment */ |
2d33f157 | 203 | }; |
204 | ||
d62a17ae | 205 | /* Message to tell client application that it ospf daemon is |
2d33f157 | 206 | * ready to accept opaque LSAs for a given interface or area. */ |
207 | ||
d62a17ae | 208 | struct msg_ready_notify { |
d7c0a89a QY |
209 | uint8_t lsa_type; |
210 | uint8_t opaque_type; | |
211 | uint8_t pad[2]; /* padding */ | |
d62a17ae | 212 | struct in_addr addr; /* interface address or area address */ |
2d33f157 | 213 | }; |
214 | ||
215 | /* These messages have a dynamic length depending on the embodied LSA. | |
216 | They are aligned to four octets. msg_lsa_change_notify is used for | |
217 | both LSA update and LSAs delete. */ | |
218 | ||
d62a17ae | 219 | struct msg_lsa_change_notify { |
220 | /* Used for LSA type 9 otherwise ignored */ | |
221 | struct in_addr ifaddr; | |
222 | /* Area ID. Not valid for AS-External and Opaque11 LSAs. */ | |
223 | struct in_addr area_id; | |
d7c0a89a QY |
224 | uint8_t is_self_originated; /* 1 if self originated. */ |
225 | uint8_t pad[3]; | |
d62a17ae | 226 | struct lsa_header data; |
2d33f157 | 227 | }; |
228 | ||
d62a17ae | 229 | struct msg_new_if { |
230 | struct in_addr ifaddr; /* interface IP address */ | |
231 | struct in_addr area_id; /* area this interface belongs to */ | |
2d33f157 | 232 | }; |
233 | ||
d62a17ae | 234 | struct msg_del_if { |
235 | struct in_addr ifaddr; /* interface IP address */ | |
2d33f157 | 236 | }; |
237 | ||
d62a17ae | 238 | struct msg_ism_change { |
239 | struct in_addr ifaddr; /* interface IP address */ | |
240 | struct in_addr area_id; /* area this interface belongs to */ | |
d7c0a89a QY |
241 | uint8_t status; /* interface status (up/down) */ |
242 | uint8_t pad[3]; /* not used */ | |
2d33f157 | 243 | }; |
244 | ||
d62a17ae | 245 | struct msg_nsm_change { |
246 | struct in_addr ifaddr; /* attached interface */ | |
247 | struct in_addr nbraddr; /* Neighbor interface address */ | |
248 | struct in_addr router_id; /* Router ID of neighbor */ | |
d7c0a89a QY |
249 | uint8_t status; /* NSM status */ |
250 | uint8_t pad[3]; | |
2d33f157 | 251 | }; |
252 | ||
149491af CH |
253 | struct msg_reachable_change { |
254 | uint16_t nadd; | |
255 | uint16_t nremove; | |
256 | struct in_addr router_ids[]; /* add followed by remove */ | |
257 | }; | |
258 | ||
44038c7a CH |
259 | struct msg_router_id_change { |
260 | struct in_addr router_id; /* this systems router id */ | |
261 | }; | |
262 | ||
2d33f157 | 263 | /* We make use of a union to define a structure that covers all |
264 | possible API messages. This allows us to find out how much memory | |
265 | needs to be reserved for the largest API message. */ | |
d62a17ae | 266 | struct apimsg { |
267 | struct apimsghdr hdr; | |
268 | union { | |
269 | struct msg_register_opaque_type register_opaque_type; | |
270 | struct msg_register_event register_event; | |
271 | struct msg_sync_lsdb sync_lsdb; | |
272 | struct msg_originate_request originate_request; | |
273 | struct msg_delete_request delete_request; | |
274 | struct msg_reply reply; | |
275 | struct msg_ready_notify ready_notify; | |
276 | struct msg_new_if new_if; | |
277 | struct msg_del_if del_if; | |
278 | struct msg_ism_change ism_change; | |
279 | struct msg_nsm_change nsm_change; | |
280 | struct msg_lsa_change_notify lsa_change_notify; | |
149491af | 281 | struct msg_reachable_change reachable_change; |
44038c7a | 282 | struct msg_router_id_change router_id_change; |
d62a17ae | 283 | } u; |
2d33f157 | 284 | }; |
285 | ||
319cfdc7 | 286 | #define OSPF_API_MAX_MSG_SIZE (sizeof(struct apimsg) + OSPF_MAX_PACKET_SIZE) |
2d33f157 | 287 | |
288 | /* ----------------------------------------------------------- | |
289 | * Prototypes for specific messages | |
290 | * ----------------------------------------------------------- | |
291 | */ | |
292 | ||
293 | /* For debugging only. */ | |
8db278b5 | 294 | extern void api_opaque_lsa_print(struct ospf_lsa *lsa); |
2d33f157 | 295 | |
296 | /* Messages sent by client */ | |
d7c0a89a QY |
297 | extern struct msg *new_msg_register_opaque_type(uint32_t seqnum, uint8_t ltype, |
298 | uint8_t otype); | |
299 | extern struct msg *new_msg_register_event(uint32_t seqnum, | |
d62a17ae | 300 | struct lsa_filter_type *filter); |
d7c0a89a | 301 | extern struct msg *new_msg_sync_lsdb(uint32_t seqnum, |
d62a17ae | 302 | struct lsa_filter_type *filter); |
d7c0a89a | 303 | extern struct msg *new_msg_originate_request(uint32_t seqnum, |
d62a17ae | 304 | struct in_addr ifaddr, |
305 | struct in_addr area_id, | |
306 | struct lsa_header *data); | |
08172828 | 307 | extern struct msg *new_msg_delete_request(uint32_t seqnum, struct in_addr addr, |
d7c0a89a | 308 | uint8_t lsa_type, uint8_t opaque_type, |
2f30cb25 | 309 | uint32_t opaque_id, uint8_t flags); |
2d33f157 | 310 | |
311 | /* Messages sent by OSPF daemon */ | |
d7c0a89a | 312 | extern struct msg *new_msg_reply(uint32_t seqnum, uint8_t rc); |
2d33f157 | 313 | |
d7c0a89a QY |
314 | extern struct msg *new_msg_ready_notify(uint32_t seqnr, uint8_t lsa_type, |
315 | uint8_t opaque_type, | |
d62a17ae | 316 | struct in_addr addr); |
2d33f157 | 317 | |
d7c0a89a | 318 | extern struct msg *new_msg_new_if(uint32_t seqnr, struct in_addr ifaddr, |
d62a17ae | 319 | struct in_addr area); |
2d33f157 | 320 | |
d7c0a89a | 321 | extern struct msg *new_msg_del_if(uint32_t seqnr, struct in_addr ifaddr); |
2d33f157 | 322 | |
d7c0a89a QY |
323 | extern struct msg *new_msg_ism_change(uint32_t seqnr, struct in_addr ifaddr, |
324 | struct in_addr area, uint8_t status); | |
2d33f157 | 325 | |
d7c0a89a | 326 | extern struct msg *new_msg_nsm_change(uint32_t seqnr, struct in_addr ifaddr, |
d62a17ae | 327 | struct in_addr nbraddr, |
d7c0a89a | 328 | struct in_addr router_id, uint8_t status); |
2d33f157 | 329 | |
330 | /* msgtype is MSG_LSA_UPDATE_NOTIFY or MSG_LSA_DELETE_NOTIFY */ | |
d7c0a89a | 331 | extern struct msg *new_msg_lsa_change_notify(uint8_t msgtype, uint32_t seqnum, |
d62a17ae | 332 | struct in_addr ifaddr, |
333 | struct in_addr area_id, | |
d7c0a89a | 334 | uint8_t is_self_originated, |
d62a17ae | 335 | struct lsa_header *data); |
2d33f157 | 336 | |
149491af CH |
337 | extern struct msg *new_msg_reachable_change(uint32_t seqnum, uint16_t nadd, |
338 | struct in_addr *add, | |
339 | uint16_t nremove, | |
340 | struct in_addr *remove); | |
44038c7a CH |
341 | |
342 | extern struct msg *new_msg_router_id_change(uint32_t seqnr, | |
343 | struct in_addr router_id); | |
2d33f157 | 344 | /* string printing functions */ |
d62a17ae | 345 | extern const char *ospf_api_errname(int errcode); |
346 | extern const char *ospf_api_typename(int msgtype); | |
2d33f157 | 347 | |
348 | #endif /* _OSPF_API_H */ |