blob: 7321bf683c8034fe667ee057d45f76e314297bdb [file] [log] [blame]
paul2d33f152003-03-17 01:10:58 +00001/*
2 * Simple main program to demonstrate how OSPF API can be used.
3 */
4
5/* The following includes are needed in all OSPF API client
6 applications */
7
8#include <zebra.h>
9#include "prefix.h" /* for ospf_asbr.h */
10
11#include "ospfd/ospfd.h"
12#include "ospfd/ospf_asbr.h"
13#include "ospfd/ospf_lsa.h"
14#include "ospfd/ospf_opaque.h"
15#include "ospfd/ospf_lsdb.h"
16#include "ospfd/ospf_dump.h"
17#include "ospfd/ospf_api.h"
18#include "ospf_apiclient.h"
19
20/* The following includes are specific to this main application. Here
21 main uses the thread functionality from libzebra (however an
22 application can use any thread library like pthreads) */
23
24#include "thread.h"
25#include "log.h"
26
27/* local portnumber for async channel */
28#define ASYNCPORT 4000
29
30/* Master thread */
31struct thread_master *master;
32
33/* Global variables */
34struct ospf_apiclient *oclient;
35char **args;
36
37/* Our opaque LSAs have the following format */
38struct my_opaque_lsa
39{
40 struct lsa_header hdr;
41 u_char data[4];
42};
43
44
45/* ---------------------------------------------------------
46 * Threads for asynchronous messages and LSA update/delete
47 * ---------------------------------------------------------
48 */
49
50int
51lsa_delete (struct thread *t)
52{
53 struct ospf_apiclient *oclient;
54 struct in_addr area_id;
55 int rc;
56
57 oclient = THREAD_ARG (t);
58
59 inet_aton (args[6], &area_id);
60
61 printf ("Deleting LSA... ");
62 rc = ospf_apiclient_lsa_delete (oclient,
63 area_id,
64 atoi (args[2]), /* lsa type */
65 atoi (args[3]), /* opaque type */
66 atoi (args[4])); /* opaque ID */
67 printf ("done, return code is = %d\n", rc);
68 return rc;
69}
70
71int
72lsa_inject (struct thread *t)
73{
74 struct ospf_apiclient *cl;
75 struct in_addr ifaddr;
76 struct in_addr area_id;
77 u_char lsa_type;
78 u_char opaque_type;
79 u_int32_t opaque_id;
80 void *opaquedata;
81 int opaquelen;
82
83 static u_int32_t counter = 1; /* Incremented each time */
84 int rc;
85
86 cl = THREAD_ARG (t);
87
88 inet_aton (args[5], &ifaddr);
89 inet_aton (args[6], &area_id);
90 lsa_type = atoi (args[2]);
91 opaque_type = atoi (args[3]);
92 opaque_id = atoi (args[4]);
93 opaquedata = &counter;
94 opaquelen = sizeof (u_int32_t);
95
96 printf ("Originating/updating LSA with counter=%d... ", counter);
97 rc = ospf_apiclient_lsa_originate(cl, ifaddr, area_id,
98 lsa_type,
99 opaque_type, opaque_id,
100 opaquedata, opaquelen);
101
102 printf ("done, return code is %d\n", rc);
103
104 counter++;
105
106 return 0;
107};
108
109
110/* This thread handles asynchronous messages coming in from the OSPF
111 API server */
112int
113lsa_read (struct thread *thread)
114{
115 struct ospf_apiclient *oclient;
116 int fd;
117 int ret;
118
119 printf ("lsa_read called\n");
120
121 oclient = THREAD_ARG (thread);
122 fd = THREAD_FD (thread);
123
124 /* Handle asynchronous message */
125 ret = ospf_apiclient_handle_async (oclient);
126 if (ret < 0) {
127 printf ("Connection closed, exiting...");
128 exit(0);
129 }
130
131 /* Reschedule read thread */
132 thread_add_read (master, lsa_read, oclient, fd);
133
134 return 0;
135}
136
137
138
139/* ---------------------------------------------------------
140 * Callback functions for asynchronous events
141 * ---------------------------------------------------------
142 */
143
144void
145lsa_update_callback (struct in_addr ifaddr, struct in_addr area_id,
146 u_char is_self_originated,
147 struct lsa_header *lsa)
148{
149 printf ("lsa_update_callback: ");
150 printf ("ifaddr: %s ", inet_ntoa (ifaddr));
151 printf ("area: %s\n", inet_ntoa (area_id));
152 printf ("is_self_origin: %u\n", is_self_originated);
153
154 ospf_lsa_header_dump (lsa);
155}
156
157void
158lsa_delete_callback (struct in_addr ifaddr, struct in_addr area_id,
159 u_char is_self_originated,
160 struct lsa_header *lsa)
161{
162 printf ("lsa_delete_callback: ");
163 printf ("ifaddr: %s ", inet_ntoa (ifaddr));
164 printf ("area: %s\n", inet_ntoa (area_id));
165 printf ("is_self_origin: %u\n", is_self_originated);
166
167 ospf_lsa_header_dump (lsa);
168}
169
170void
171ready_callback (u_char lsa_type, u_char opaque_type, struct in_addr addr)
172{
173 printf ("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
174 lsa_type, opaque_type, inet_ntoa (addr));
175
176 /* Schedule opaque LSA originate in 5 secs */
177 thread_add_timer (master, lsa_inject, oclient, 5);
178
179 /* Schedule opaque LSA update with new value */
180 thread_add_timer (master, lsa_inject, oclient, 10);
181
182 /* Schedule delete */
183 thread_add_timer (master, lsa_delete, oclient, 30);
184}
185
186void
187new_if_callback (struct in_addr ifaddr, struct in_addr area_id)
188{
189 printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr));
190 printf ("area_id: %s\n", inet_ntoa (area_id));
191}
192
193void
194del_if_callback (struct in_addr ifaddr)
195{
196 printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr));
197}
198
199void
200ism_change_callback (struct in_addr ifaddr, struct in_addr area_id,
201 u_char state)
202{
203 printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr));
204 printf ("area_id: %s\n", inet_ntoa (area_id));
205 printf ("state: %d [%s]\n", state, LOOKUP (ospf_ism_state_msg, state));
206}
207
208void
209nsm_change_callback (struct in_addr ifaddr, struct in_addr nbraddr,
210 struct in_addr router_id, u_char state)
211{
212 printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr));
213 printf ("nbraddr: %s\n", inet_ntoa (nbraddr));
214 printf ("router_id: %s\n", inet_ntoa (router_id));
215 printf ("state: %d [%s]\n", state, LOOKUP (ospf_nsm_state_msg, state));
216}
217
218
219/* ---------------------------------------------------------
220 * Main program
221 * ---------------------------------------------------------
222 */
223
224int
225main (int argc, char *argv[])
226{
227 struct thread thread;
228
229 args = argv;
230
231 /* Main should be started with the following arguments:
232 *
233 * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr
234 * (6) area_id
235 *
236 * host: name or IP of host where ospfd is running
237 * lsa_type: 9, 10, or 11
238 * opaque_type: 0-255 (e.g., 140 for experimental Active Networking)
239 * opaque_id: arbitrary application instance (24 bits)
240 * if_addr: interface IP address (for type 9) otherwise ignored
241 * area_id: area in IP address format (for type 10) otherwise ignored
242 */
243
244 if (argc != 7)
245 {
246 printf ("main: wrong number of arguments!\n");
247 exit (1);
248 }
249
250 /* Initialization */
251 master = thread_master_create ();
252
253 /* Open connection to OSPF daemon */
254 oclient = ospf_apiclient_connect (args[1], ASYNCPORT);
255 if (!oclient)
256 {
257 printf ("main: connect failed!\n");
258 exit (1);
259 }
260
261 /* Register callback functions. */
262 ospf_apiclient_register_callback (oclient,
263 ready_callback,
264 new_if_callback,
265 del_if_callback,
266 ism_change_callback,
267 nsm_change_callback,
268 lsa_update_callback,
269 lsa_delete_callback);
270
271 /* Register LSA type and opaque type. */
272 ospf_apiclient_register_opaque_type (oclient, atoi (args[2]),
273 atoi (args[3]));
274
275 /* Synchronize database with OSPF daemon. */
276 ospf_apiclient_sync_lsdb (oclient);
277
278 /* Schedule thread that handles asynchronous messages */
279 thread_add_read (master, lsa_read, oclient, oclient->fd_async);
280
281 /* Now connection is established, run loop */
282 while (1)
283 {
284 thread_fetch (master, &thread);
285 thread_call (&thread);
286 }
287
288 /* Never reached */
289 return 0;
290}
291