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 */
16 #include "ospfd/ospfd.h"
17 #include "ospfd/ospf_asbr.h"
18 #include "ospfd/ospf_lsa.h"
19 #include "ospfd/ospf_opaque.h"
20 #include "ospfd/ospf_api.h"
21 #include "ospf_apiclient.h"
24 * set cap_num_* and uid/gid to nothing to use NULL privs
25 * as ospfapiclient links in libospf.a which uses privs.
27 struct zebra_privs_t ospfd_privs
=
35 /* The following includes are specific to this application. For
36 example it uses threads from libzebra, however your application is
37 free to use any thread library (like pthreads). */
39 #include "ospfd/ospf_dump.h" /* for ospf_lsa_header_dump */
43 /* Local portnumber for async channel. Note that OSPF API library will also
44 allocate a sync channel at ASYNCPORT+1. */
45 #define ASYNCPORT 4000
48 struct thread_master
*master
;
50 /* Global variables */
51 struct ospf_apiclient
*oclient
;
54 /* Our opaque LSAs have the following format. */
57 struct lsa_header hdr
; /* include common LSA header */
58 u_char data
[4]; /* our own data format then follows here */
62 /* ---------------------------------------------------------
63 * Threads for asynchronous messages and LSA update/delete
64 * ---------------------------------------------------------
68 lsa_delete (struct thread
*t
)
70 struct ospf_apiclient
*oclient
;
71 struct in_addr area_id
;
74 oclient
= THREAD_ARG (t
);
76 inet_aton (args
[6], &area_id
);
78 printf ("Deleting LSA... ");
79 rc
= ospf_apiclient_lsa_delete (oclient
,
81 atoi (args
[2]), /* lsa type */
82 atoi (args
[3]), /* opaque type */
83 atoi (args
[4])); /* opaque ID */
84 printf ("done, return code is = %d\n", rc
);
89 lsa_inject (struct thread
*t
)
91 struct ospf_apiclient
*cl
;
92 struct in_addr ifaddr
;
93 struct in_addr area_id
;
100 static u_int32_t counter
= 1; /* Incremented each time invoked */
105 inet_aton (args
[5], &ifaddr
);
106 inet_aton (args
[6], &area_id
);
107 lsa_type
= atoi (args
[2]);
108 opaque_type
= atoi (args
[3]);
109 opaque_id
= atoi (args
[4]);
110 opaquedata
= &counter
;
111 opaquelen
= sizeof (u_int32_t
);
113 printf ("Originating/updating LSA with counter=%d... ", counter
);
114 rc
= ospf_apiclient_lsa_originate(cl
, ifaddr
, area_id
,
116 opaque_type
, opaque_id
,
117 opaquedata
, opaquelen
);
119 printf ("done, return code is %d\n", rc
);
127 /* This thread handles asynchronous messages coming in from the OSPF
130 lsa_read (struct thread
*thread
)
132 struct ospf_apiclient
*oclient
;
136 printf ("lsa_read called\n");
138 oclient
= THREAD_ARG (thread
);
139 fd
= THREAD_FD (thread
);
141 /* Handle asynchronous message */
142 ret
= ospf_apiclient_handle_async (oclient
);
144 printf ("Connection closed, exiting...");
148 /* Reschedule read thread */
149 thread_add_read (master
, lsa_read
, oclient
, fd
);
154 /* ---------------------------------------------------------
155 * Callback functions for asynchronous events
156 * ---------------------------------------------------------
160 lsa_update_callback (struct in_addr ifaddr
, struct in_addr area_id
,
161 u_char is_self_originated
,
162 struct lsa_header
*lsa
)
164 printf ("lsa_update_callback: ");
165 printf ("ifaddr: %s ", inet_ntoa (ifaddr
));
166 printf ("area: %s\n", inet_ntoa (area_id
));
167 printf ("is_self_origin: %u\n", is_self_originated
);
169 /* It is important to note that lsa_header does indeed include the
170 header and the LSA payload. To access the payload, first check
171 the LSA type and then typecast lsa into the corresponding type,
174 if (lsa->type == OSPF_ROUTER_LSA) {
175 struct router_lsa *rl = (struct router_lsa) lsa;
177 u_int16_t links = rl->links;
182 ospf_lsa_header_dump (lsa
);
186 lsa_delete_callback (struct in_addr ifaddr
, struct in_addr area_id
,
187 u_char is_self_originated
,
188 struct lsa_header
*lsa
)
190 printf ("lsa_delete_callback: ");
191 printf ("ifaddr: %s ", inet_ntoa (ifaddr
));
192 printf ("area: %s\n", inet_ntoa (area_id
));
193 printf ("is_self_origin: %u\n", is_self_originated
);
195 ospf_lsa_header_dump (lsa
);
199 ready_callback (u_char lsa_type
, u_char opaque_type
, struct in_addr addr
)
201 printf ("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
202 lsa_type
, opaque_type
, inet_ntoa (addr
));
204 /* Schedule opaque LSA originate in 5 secs */
205 thread_add_timer (master
, lsa_inject
, oclient
, 5);
207 /* Schedule opaque LSA update with new value */
208 thread_add_timer (master
, lsa_inject
, oclient
, 10);
210 /* Schedule delete */
211 thread_add_timer (master
, lsa_delete
, oclient
, 30);
215 new_if_callback (struct in_addr ifaddr
, struct in_addr area_id
)
217 printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr
));
218 printf ("area_id: %s\n", inet_ntoa (area_id
));
222 del_if_callback (struct in_addr ifaddr
)
224 printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr
));
228 ism_change_callback (struct in_addr ifaddr
, struct in_addr area_id
,
231 printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr
));
232 printf ("area_id: %s\n", inet_ntoa (area_id
));
233 printf ("state: %d [%s]\n", state
, LOOKUP (ospf_ism_state_msg
, state
));
237 nsm_change_callback (struct in_addr ifaddr
, struct in_addr nbraddr
,
238 struct in_addr router_id
, u_char state
)
240 printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr
));
241 printf ("nbraddr: %s\n", inet_ntoa (nbraddr
));
242 printf ("router_id: %s\n", inet_ntoa (router_id
));
243 printf ("state: %d [%s]\n", state
, LOOKUP (ospf_nsm_state_msg
, state
));
247 /* ---------------------------------------------------------
249 * ---------------------------------------------------------
254 printf("Usage: ospfclient <ospfd> <lsatype> <opaquetype> <opaqueid> <ifaddr> <areaid>\n");
255 printf("where ospfd : router where API-enabled OSPF daemon is running\n");
256 printf(" lsatype : either 9, 10, or 11 depending on flooding scope\n");
257 printf(" opaquetype: 0-255 (e.g., experimental applications use > 128)\n");
258 printf(" opaqueid : arbitrary application instance (24 bits)\n");
259 printf(" ifaddr : interface IP address (for type 9) otherwise ignored\n");
260 printf(" areaid : area in IP address format (for type 10) otherwise ignored\n");
266 main (int argc
, char *argv
[])
268 struct thread thread
;
272 /* ospfclient should be started with the following arguments:
274 * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr
277 * host: name or IP of host where ospfd is running
278 * lsa_type: 9, 10, or 11
279 * opaque_type: 0-255 (e.g., experimental applications use > 128)
280 * opaque_id: arbitrary application instance (24 bits)
281 * if_addr: interface IP address (for type 9) otherwise ignored
282 * area_id: area in IP address format (for type 10) otherwise ignored
291 zprivs_init (&ospfd_privs
);
292 master
= thread_master_create ();
294 /* Open connection to OSPF daemon */
295 oclient
= ospf_apiclient_connect (args
[1], ASYNCPORT
);
298 printf ("Connecting to OSPF daemon on %s failed!\n",
303 /* Register callback functions. */
304 ospf_apiclient_register_callback (oclient
,
311 lsa_delete_callback
);
313 /* Register LSA type and opaque type. */
314 ospf_apiclient_register_opaque_type (oclient
, atoi (args
[2]),
317 /* Synchronize database with OSPF daemon. */
318 ospf_apiclient_sync_lsdb (oclient
);
320 /* Schedule thread that handles asynchronous messages */
321 thread_add_read (master
, lsa_read
, oclient
, oclient
->fd_async
);
323 /* Now connection is established, run loop */
326 thread_fetch (master
, &thread
);
327 thread_call (&thread
);