~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
cvs/emstar/devel/herd/dsr/dsr_upper.c


  1 /*
  2  *
  3  * Copyright (c) 2003 The Regents of the University of California.  All
  4  * rights reserved.
  5  *
  6  * Redistribution and use in source and binary forms, with or without
  7 * modification, are permitted provided that the following conditions
  8  * are met:
  9  *
 10  * - Redistributions of source code must retain the above copyright
 11  *   notice, this list of conditions and the following disclaimer.
 12  *
 13  * - Neither the name of the University nor the names of its
 14  *   contributors may be used to endorse or promote products derived
 15  *   from this software without specific prior written permission.
 16  *
 17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 19  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 20  * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28  *
 29  */
 30 
 31 
 32 #include <stdio.h>
 33 #include <stdlib.h>
 34 #include <unistd.h>
 35 #include <ctype.h>
 36 #include <sys/time.h>
 37 #include <arpa/inet.h>
 38 #include <math.h>
 39 
 40 #include "emrun/emrun.h"
 41 #include "link/link.h"
 42 #include <link/link_headers.h>
 43 #include <libmisc/misc.h>
 44 #include <libdev/status_dev.h>
 45 #include <libdev/command_dev.h>
 46 #include <libdev/query_dev.h>
 47 #include <libdev/packet_client.h>
 48 #include <libdev/packet_dev.h>
 49 #include <libdev/em_sched.h>
 50 #include <dsr_i.h>
 51 #include <routing/routing_table.h>
 52 #include <libdev/command_dev.h>
 53 #include <devel/state/ssync.h>
 54 
 55 
 56 int dsr_upper_send(lp_context_t *lp, link_pkt_t *pkt, int datalen,
 57         int loop_needed);
 58 int dsr_upper_status(lp_context_t *lp);
 59 int dsr_upper_ioctl(lp_context_t *lp, int cmd, void *arg);
 60 int dsr_upper_parse_commands(lp_context_t *lp, parser_state_t *cmd_input);
 61 void dsr_upper_usage(lp_context_t *lp, buf_t *buf);
 62 int dsr_upper_enqueue(lp_context_t *lp, link_pkt_t *pkt, int datalen);
 63 
 64 int flush_timer_expired(void *data, int interval, g_event_t *ev)
 65 {
 66     dsr_rtable_entry_t *rtentry = (dsr_rtable_entry_t *)(data);
 67 
 68     if (rtentry->flush_pending == 1) {
 69         flush_pkt_queue(rtentry);
 70     }
 71     rtentry->flush_pending = 0;
 72 
 73     return TIMER_DONE;
 74 }
 75 
 76 
 77 
 78 int dsr_upper_enqueue(lp_context_t *lp, link_pkt_t *pkt, int datalen)
 79 {
 80     dsr_state_t *dstate = (dsr_state_t *)lp_data(lp);
 81     dsr_rtable_entry_t *rtentry=NULL;
 82 
 83     // if we're off, return EAGAIN at once
 84     if (dstate->cmd_status == STATE_OFF) {
 85         return -EAGAIN;
 86     }
 87 
 88     if (pkt->dst.id == LINK_BROADCAST) {
 89         // We don't support broadcasts for now
 90         elog(LOG_ERR, "Broadcast destination not supported yet!!!");
 91         return -EDESTADDRREQ;
 92     }
 93 
 94     rtentry = find_routing_table_entry_for_destination(pkt->dst.id, dstate);
 95 
 96     if (rtentry == NULL) {
 97         goto done;
 98     }
 99 
100 
101 //    if ((rtentry->status != ENTRY_PATH_EXISTS) &&
102       if (pending_pkts_list_qlen(rtentry) > 
103             dstate->max_pending_pkt_queue_size) {
104         // path doesn't exist and queue is full!
105         elog(LOG_ERR, "Cant enqueue pkt, internal destination (%d)"
106                 " queue full", rtentry->dst);
107 
108         // I should really start a timer and if the queue is full when it
109         // expires, THEN flush it
110         if (g_timer_isset(rtentry->flush_timer)==0) {
111             g_timer_add(dstate->flush_timeout_sec, flush_timer_expired,
112                     rtentry, NULL, &(rtentry->flush_timer));
113         }
114         rtentry->flush_pending = 1;
115 
116         return -EAGAIN;
117     }
118 
119 done:
120     return 0;
121 }
122 
123 
124 
125 int dsr_upper_send(lp_context_t *lp, link_pkt_t *pkt, int datalen,
126         int loop_needed)
127 {
128     dsr_state_t *dstate = (dsr_state_t *)lp_data(lp);
129     dsr_rtable_entry_t *rtentry=NULL;
130     int retval = 0;
131     int block = 0;
132     link_pkt_t *link_pkt = (link_pkt_t *)pkt;
133 
134     // XXX XXX XXX
135     // WE ASSUME THAT THE USER OF UPPER USES NODE_IDS NOT IF_IDS!!!
136 
137     if (pkt->dst.id == my_node_id) {
138         // if I am sending a pkt to myself, immediately deliver it upwards
139         lp_receive(lp, pkt, datalen);
140         goto done;
141     }
142 
143     rtentry = find_routing_table_entry_for_destination(pkt->dst.id, dstate);
144 
145     if (rtentry==NULL) {
146         // destination doesn't exist in our table, create it
147         rtentry = create_rtable_entry(pkt->dst.id, dstate);
148         if (rtentry==NULL) {
149             elog(LOG_ERR, "Could not create routing table entry!");
150             exit(1);
151         }
152     }
153 
154     // rtentry is valid 
155     //
156     // check if we have a valid path to that destination
157     if (path_exists(rtentry) == 0) {
158         // path is invalid
159         // 
160         // 1. Enqueue the packet in rtentry's queue
161         // 2. *MAYBE* send RREQ (based on our rreq rate limiting timer)
162         //
163         enqueue_pending_pkt(pkt, datalen, rtentry);
164         maybe_send_rreq(rtentry, dstate);
165         block = 0;
166         goto done;
167 
168     } else {  
169         // send the pkt to the lower interface
170         // this function will take care of header settings, table lookups
171         // etc
172         retval = send_pkt_to_lower(pkt, datalen, rtentry, dstate);
173         block = 1;
174     }
175         
176 done:
177     if (loop_needed) {
178         link_pkt->src.id = my_node_id;
179         lp_loop_receive(lp, link_pkt, datalen);
180     }
181 
182     //if we ended up calling send_to_lower, block
183     if (block) {
184         return LP_BLOCKED;
185     } else {
186         return 0;
187     }
188 }
189 
190 
191 
192 int dsr_upper_status(lp_context_t *lp)
193 {
194     return EVENT_RENEW;
195 }
196 
197 
198 int dsr_upper_ioctl(lp_context_t *lp, int cmd, void *arg)
199 {
200     return 0;
201 }
202 
203 
204 int dsr_upper_parse_commands(lp_context_t *lp, parser_state_t *cmd_input)
205 {
206     return 0;
207 }
208 
209 
210 void dsr_upper_usage(lp_context_t *lp, buf_t *buf)
211 {
212 }
213 
214 
215 
216 
217 
218 
219 void dsr_init_upper(dsr_state_t *dstate)
220 {
221     lp_opts_t opts = {
222         description: "DSR routing interface",
223         opts: {
224             name: dstate->link_provides_name,
225             if_class: dstate->class_name,
226             //if_class: LINK_CLASS_ROUTING,
227             data: dstate,
228         },
229 
230 
231         initial_status : {
232             // TODO: fix the mtu!
233             MTU: dstate->provided_mtu,
234             if_id: my_node_id,
235         },
236 
237         send: dsr_upper_send,
238         enqueue: dsr_upper_enqueue,
239         status_request: dsr_upper_status,
240         ioctl: dsr_upper_ioctl,
241         command_request: dsr_upper_parse_commands,
242         usage: dsr_upper_usage,
243 
244         we_are_root:1
245     };
246 
247     if (lp_register(&opts, &(dstate->provided_link)) < 0) {
248         elog(LOG_CRIT, "Can't create link device %s: %m",
249                 link_name(&opts.opts, NULL));
250         exit(1);
251     } else {
252         elog(LOG_NOTICE, "Link device %s created", 
253                 link_name(&opts.opts, NULL));
254     }
255     
256 }
257 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.