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

Linux Cross Reference
cvs/emstar/routing/geo-linkstate/gls_lower.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 
 33 #include "common.h"
 34 #include "gls_i.h"
 35 #include "hash.h"
 36 #include "dijkstra.h"
 37 
 38 extern node_id_t my_node_id;
 39 extern loc_t my_loc;
 40 
 41 #define MY_LOG_LEVEL LOG_DEBUG(4)
 42 
 43 static void gls_upcall_to_user (gls_state_t *gls_state, ssize_t data_len, link_pkt_t *link_pkt_in)
 44 {
 45   /* Get the gls packet from link packet */
 46   gls_pkt_t *gls_pkt_in = (gls_pkt_t *) link_pkt_in->data;  
 47 
 48   link_pkt_t up_link_hdr = {
 49     src: {
 50       loc: {
 51         x: loc_expand(gls_pkt_in->original_src.addr.geo.x),   /* set src to original src location */
 52         y: loc_expand(gls_pkt_in->original_src.addr.geo.y),
 53       },
 54     },
 55     dst: {
 56       loc: {
 57         x: loc_expand(gls_pkt_in->final_dst.addr.geo.x),  /* set dst to the final dst loc */
 58         y: loc_expand(gls_pkt_in->final_dst.addr.geo.y),
 59       },
 60     },
 61     type: gls_pkt_in->inner_type, /* set type to application type */
 62   };
 63   
 64   buf_t *up_pkt = buf_new();
 65   
 66   elog (LOG_DEBUG_0, "Upcall to user");
 67   
 68   /* first construct the link header */
 69   bufcpy(up_pkt, &up_link_hdr, sizeof(up_link_hdr));
 70   
 71   /* the gls header has been stripped out, so only copy user data  */
 72   
 73   /* followed by user data */
 74   bufcpy(up_pkt, gls_pkt_in->data, data_len - sizeof(gls_pkt_t));
 75 
 76   /* For debugging. Spit out packet contents */
 77   elog(MY_LOG_LEVEL, "Printing Packet: Datalen:%d glspktsize:%d link_hdr:%d",
 78        data_len,sizeof(gls_pkt_t), sizeof(link_pkt_in));
 79   elog_raw(MY_LOG_LEVEL, gls_pkt_in->data, data_len - sizeof(gls_pkt_t));
 80   elog(MY_LOG_LEVEL, "Full Packet");
 81   elog_raw(MY_LOG_LEVEL, link_pkt_in->data, data_len);
 82   
 83   /* send it up */
 84   pd_receive(gls_state->pd_context, up_pkt->buf, up_pkt->len);
 85   
 86   /* free the buffer that we created */
 87   buf_free(up_pkt);
 88 }
 89 
 90 /*
 91  * This callback is called whenever a packet arrives up from one of
 92  * the underlying datalink interfaces
 93  */
 94 static int gls_receiver(link_pkt_t *link_pkt_in, ssize_t data_len, link_context_t *link)
 95 {
 96   /* Get out state pointer */
 97   gls_state_t *gls_state = (gls_state_t *) link_opts(link)->data;
 98   /* Get the gls packet from link packet */
 99   gls_pkt_t *gls_pkt_in = (gls_pkt_t *) link_pkt_in->data;
100 
101   /* address/location to be looked up */
102   /* assume that input address is geographic */
103   gls_addr_t gls_addr_in = {
104     addr: {
105       geo: gls_pkt_in->final_dst.addr.geo,
106     },
107     type: ADDR_GEO,
108   };
109   /* address after lookup */
110   gls_addr_t gls_addr_out;
111   /* result of lookup */
112   gboolean lookup_result=FALSE;
113 
114   elog(LOG_NOTICE, "RECEIVE DATA SIZE: %d", data_len);
115 
116   elog (MY_LOG_LEVEL, "got packet OrigSrc:%2.2f,%2.2f FinalDst:%2.2f,%2.2f",
117         loc_expand(gls_pkt_in->original_src.addr.geo.x), 
118         loc_expand(gls_pkt_in->original_src.addr.geo.y),
119         loc_expand(gls_pkt_in->final_dst.addr.geo.x), 
120         loc_expand(gls_pkt_in->final_dst.addr.geo.y));
121   
122   /*
123    * Make sure the packet has the right packet type.  Since we
124    * specified the desired packet type when we registered to receive
125    * packets, this test should never fail.
126    */
127   if (link_pkt_in->type != PKT_TYPE_GLS) {
128     elog(LOG_WARNING, "got a packet not meant for us - filter failed!");
129     goto done;
130   }
131 
132   /*
133    * Make sure the data portion of the packet is at least the size of
134    * a gls header
135    */
136   if (data_len < sizeof(gls_pkt_t)) {
137     elog(LOG_ERR, "got a short gls packet (%d bytes < %d)!", data_len,
138          sizeof(gls_pkt_t));
139     goto done;
140   }
141   
142   /* We want nodeid output, so set output type to nodeid */
143   gls_addr_out.type = ADDR_NODEID;
144 
145   /* Lookup next hop to dst */
146   get_nexthop_to_dest_loc(&gls_addr_in, &gls_addr_out,
147                           &lookup_result, gls_state->info);
148 
149   /* drop pkt if no route to dst can be found */
150   /* XXX: Remember to free packet */
151   if (!lookup_result) goto done;
152 
153   /* Send it up the stack if we are the 
154    * node closest to destination location */
155 /*   if (gls_addr_out.addr.nodeid == my_node_id) { */
156 /*     goto done; */
157 /*   } */
158 
159   /* Decrement ttl; throw it away if it has hit zero */
160 /*   if (--(gls_pkt_in->ttl) <= 0) */
161 /*     goto done; */
162 
163   if ((node_id_t)gls_addr_out.addr.nodeid == my_node_id) {
164     elog (MY_LOG_LEVEL, "Upcall: OrigSrc:%2.2f,%2.2f FinalDst:%2.2f,%2.2f",
165           loc_expand(gls_pkt_in->original_src.addr.geo.x), 
166           loc_expand(gls_pkt_in->original_src.addr.geo.y),
167           loc_expand(gls_pkt_in->final_dst.addr.geo.x), 
168           loc_expand(gls_pkt_in->final_dst.addr.geo.y));
169   }
170 
171   /* forward received pkt to next_hop. Size of packet is unchanged */
172   gls_forward(gls_state, link_pkt_in, 
173               data_len, (node_id_t)gls_addr_out.addr.nodeid);
174 
175  done:
176   free(link_pkt_in);
177   return EVENT_RENEW;
178 }
179 
180 
181 /*
182  * This function opens one of the underlying transport devices used by
183  * the gls daemon (e.g., a basic datalink such as motenic)
184  * XXX: Use only once?
185  */
186 void gls_open_link(gls_state_t *g, int link_index)
187 {
188   gls_iface_t *i;
189 
190   /* get a pointer to the next available iface struct */
191   i = &(g->iface);
192 
193   /* set options for this link */
194   memset(i, 0, sizeof(gls_iface_t));
195   i->if_opts.link_index = link_index;
196   i->if_opts.pkt_type = PKT_TYPE_GLS;
197   i->if_opts.q_opts.outq_len = 1000;
198   i->if_opts.q_opts.inq_len = 1000;
199   i->if_opts.receive = gls_receiver;
200   i->if_opts.data = g;
201 
202   /* try to open it */
203   if (link_open(&i->if_opts, &i->if_context) < 0) {
204     elog(LOG_CRIT, "can't open %s: %m", link_name(&i->if_opts));
205     exit(1);
206   }
207 
208   /* Open succeeded - increment interface count */
209   elog(LOG_NOTICE, "opened lower interface: %s",link_name(&i->if_opts));
210 }
211 
212 
213 /*
214  * Send a link_pkt to all interfaces opened by the function above
215  */
216 void gls_forward (gls_state_t *gls_state, link_pkt_t *pkt, 
217                   ssize_t data_len, node_id_t next_hop)
218 {
219   int i;
220   if_id_t if_out; /* output interface */
221 
222   /* Check if we are the next hop. If so, pass packet up and return */
223   if (next_hop == my_node_id) {
224     gls_upcall_to_user (gls_state, data_len, pkt);
225     return;
226   }
227   
228   /* Find interface that next_hop corresponds to */
229   /* XXX: remove copy of interface */
230   for (i = 0; i < gls_state->nb_list_count; i++)
231     if (gls_state->nb_list[i].node_id == next_hop) {
232       if_out = gls_state->nb_list[i].if_id;
233       break;
234     }
235 
236   elog(LOG_NOTICE, "TRANSMIT DATA SIZE: %d", data_len);
237 
238   /* set the dst interface id to the neighbor's if_id */
239   pkt->dst.id = if_out;
240 
241   elog(MY_LOG_LEVEL, "sending to %s", link_name(link_opts(gls_state->iface.if_context)));
242   
243   if (link_send(gls_state->iface.if_context, pkt, data_len) < 0)
244     elog(LOG_WARNING, "sending to %s: %m", link_name(&(gls_state->iface.if_opts)));
245 }
246 

~ [ 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.