2 * Simple program to demonstrate how OSPF API can be used. This
3 * application retrieves the LSDB from the OSPF daemon and then
4 * originates, updates and finally deletes an application-specific
5 * opaque LSA. You can use this application as a template when writing
6 * your own application.
9 /* The following includes are needed in all OSPF API client
13 #include "prefix.h" /* needed by ospf_asbr.h */
17 #include "ospfd/ospfd.h"
18 #include "ospfd/ospf_asbr.h"
19 #include "ospfd/ospf_lsa.h"
20 #include "ospfd/ospf_opaque.h"
21 #include "ospfd/ospf_api.h"
22 #include "ospf_apiclient.h"
25 * set cap_num_* and uid/gid to nothing to use NULL privs
26 * as ospfapiclient links in libospf.a which uses privs.
28 struct zebra_privs_t ospfd_privs
=
36 /* The following includes are specific to this application. For
37 example it uses threads from libzebra, however your application is
38 free to use any thread library (like pthreads). */
40 #include "ospfd/ospf_dump.h" /* for ospf_lsa_header_dump */
44 /* Local portnumber for async channel. Note that OSPF API library will also
45 allocate a sync channel at ASYNCPORT+1. */
46 #define ASYNCPORT 4000
49 struct thread_master
*master
;
51 /* Global variables */
52 struct ospf_apiclient
*oclient
;
55 /* Our opaque LSAs have the following format. */
58 struct lsa_header hdr
; /* include common LSA header */
59 u_char data
[4]; /* our own data format then follows here */
63 /* ---------------------------------------------------------
64 * Threads for asynchronous messages and LSA update/delete
65 * ---------------------------------------------------------
69 lsa_delete (struct thread
*t
)
71 struct ospf_apiclient
*oclient
;
72 struct in_addr area_id
;
75 oclient
= THREAD_ARG (t
);
77 inet_aton (args
[6], &area_id
);
79 printf ("Deleting LSA... ");
80 rc
= ospf_apiclient_lsa_delete (oclient
,
82 atoi (args
[2]), /* lsa type */
83 atoi (args
[3]), /* opaque type */
84 atoi (args
[4])); /* opaque ID */
85 printf ("done, return code is = %d\n", rc
);
90 lsa_inject (struct thread
*t
)
92 struct ospf_apiclient
*cl
;
93 struct in_addr ifaddr
;
94 struct in_addr area_id
;
101 static u_int32_t counter
= 1; /* Incremented each time invoked */
106 inet_aton (args
[5], &ifaddr
);
107 inet_aton (args
[6], &area_id
);
108 lsa_type
= atoi (args
[2]);
109 opaque_type
= atoi (args
[3]);
110 opaque_id
= atoi (args
[4]);
111 opaquedata
= &counter
;
112 opaquelen
= sizeof (u_int32_t
);
114 printf ("Originating/updating LSA with counter=%d... ", counter
);
115 rc
= ospf_apiclient_lsa_originate(cl
, ifaddr
, area_id
,
117 opaque_type
, opaque_id
,
118 opaquedata
, opaquelen
);
120 printf ("done, return code is %d\n", rc
);
128 /* This thread handles asynchronous messages coming in from the OSPF
131 lsa_read (struct thread
*thread
)
133 struct ospf_apiclient
*oclient
;
137 printf ("lsa_read called\n");
139 oclient
= THREAD_ARG (thread
);
140 fd
= THREAD_FD (thread
);
142 /* Handle asynchronous message */
143 ret
= ospf_apiclient_handle_async (oclient
);
145 printf ("Connection closed, exiting...");
149 /* Reschedule read thread */
150 thread_add_read (master
, lsa_read
, oclient
, fd
);
155 /* ---------------------------------------------------------
156 * Callback functions for asynchronous events
157 * ---------------------------------------------------------
161 lsa_update_callback (struct in_addr ifaddr
, struct in_addr area_id
,
162 u_char is_self_originated
,
163 struct lsa_header
*lsa
)
165 printf ("lsa_update_callback: ");
166 printf ("ifaddr: %s ", inet_ntoa (ifaddr
));
167 printf ("area: %s\n", inet_ntoa (area_id
));
168 printf ("is_self_origin: %u\n", is_self_originated
);
170 /* It is important to note that lsa_header does indeed include the
171 header and the LSA payload. To access the payload, first check
172 the LSA type and then typecast lsa into the corresponding type,
175 if (lsa->type == OSPF_ROUTER_LSA) {
176 struct router_lsa *rl = (struct router_lsa) lsa;
178 u_int16_t links = rl->links;
183 ospf_lsa_header_dump (lsa
);
187 lsa_delete_callback (struct in_addr ifaddr
, struct in_addr area_id
,
188 u_char is_self_originated
,
189 struct lsa_header
*lsa
)
191 printf ("lsa_delete_callback: ");
192 printf ("ifaddr: %s ", inet_ntoa (ifaddr
));
193 printf ("area: %s\n", inet_ntoa (area_id
));
194 printf ("is_self_origin: %u\n", is_self_originated
);
196 ospf_lsa_header_dump (lsa
);
200 ready_callback (u_char lsa_type
, u_char opaque_type
, struct in_addr addr
)
202 printf ("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
203 lsa_type
, opaque_type
, inet_ntoa (addr
));
205 /* Schedule opaque LSA originate in 5 secs */
206 thread_add_timer (master
, lsa_inject
, oclient
, 5);
208 /* Schedule opaque LSA update with new value */
209 thread_add_timer (master
, lsa_inject
, oclient
, 10);
211 /* Schedule delete */
212 thread_add_timer (master
, lsa_delete
, oclient
, 30);
216 new_if_callback (struct in_addr ifaddr
, struct in_addr area_id
)
218 printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr
));
219 printf ("area_id: %s\n", inet_ntoa (area_id
));
223 del_if_callback (struct in_addr ifaddr
)
225 printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr
));
229 ism_change_callback (struct in_addr ifaddr
, struct in_addr area_id
,
232 printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr
));
233 printf ("area_id: %s\n", inet_ntoa (area_id
));
234 printf ("state: %d [%s]\n", state
, LOOKUP (ospf_ism_state_msg
, state
));
238 nsm_change_callback (struct in_addr ifaddr
, struct in_addr nbraddr
,
239 struct in_addr router_id
, u_char state
)
241 printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr
));
242 printf ("nbraddr: %s\n", inet_ntoa (nbraddr
));
243 printf ("router_id: %s\n", inet_ntoa (router_id
));
244 printf ("state: %d [%s]\n", state
, LOOKUP (ospf_nsm_state_msg
, state
));
248 /* ---------------------------------------------------------
250 * ---------------------------------------------------------
255 printf("Usage: ospfclient <ospfd> <lsatype> <opaquetype> <opaqueid> <ifaddr> <areaid>\n");
256 printf("where ospfd : router where API-enabled OSPF daemon is running\n");
257 printf(" lsatype : either 9, 10, or 11 depending on flooding scope\n");
258 printf(" opaquetype: 0-255 (e.g., experimental applications use > 128)\n");
259 printf(" opaqueid : arbitrary application instance (24 bits)\n");
260 printf(" ifaddr : interface IP address (for type 9) otherwise ignored\n");
261 printf(" areaid : area in IP address format (for type 10) otherwise ignored\n");
267 main (int argc
, char *argv
[])
269 struct thread thread
;
273 /* ospfclient should be started with the following arguments:
275 * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr
278 * host: name or IP of host where ospfd is running
279 * lsa_type: 9, 10, or 11
280 * opaque_type: 0-255 (e.g., experimental applications use > 128)
281 * opaque_id: arbitrary application instance (24 bits)
282 * if_addr: interface IP address (for type 9) otherwise ignored
283 * area_id: area in IP address format (for type 10) otherwise ignored
292 zprivs_init (&ospfd_privs
);
293 master
= thread_master_create ();
295 /* Open connection to OSPF daemon */
296 oclient
= ospf_apiclient_connect (args
[1], ASYNCPORT
);
299 printf ("Connecting to OSPF daemon on %s failed!\n",
304 /* Register callback functions. */
305 ospf_apiclient_register_callback (oclient
,
312 lsa_delete_callback
);
314 /* Register LSA type and opaque type. */
315 ospf_apiclient_register_opaque_type (oclient
, atoi (args
[2]),
318 /* Synchronize database with OSPF daemon. */
319 ospf_apiclient_sync_lsdb (oclient
);
321 /* Schedule thread that handles asynchronous messages */
322 thread_add_read (master
, lsa_read
, oclient
, oclient
->fd_async
);
324 /* Now connection is established, run loop */
327 thread_fetch (master
, &thread
);
328 thread_call (&thread
);