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