00001
00011 #include "rf.h"
00012 #include "sim_if.h"
00013 #include "virtual_time.h"
00014
00015 #include <linux/module.h>
00016 #include <linux/time.h>
00017 #include <net/ip.h>
00018 #include <net/xfrm.h>
00019 #include <net/dst.h>
00020 #include <net/inet_ecn.h>
00021 #include <net/route.h>
00022
00023 #define IPPROTO_OQIP 0x0009
00024 #define PORT 3333
00025
00026 extern struct oq_req_resp_list *req_resp_lists;
00027 extern u32 inet_select_addr(const struct net_device*, u32, int);
00028
00029 void timestamp_to_jiffies(timestamp_t stamp, unsigned long *jif)
00030 {
00031 struct timeval tv;
00032 timestamp_to_timeval(stamp, &tv);
00033 *jif = timeval_to_jiffies(&tv);
00034 }
00035
00036
00037 void jiffies_to_timestamp(unsigned long jif, timestamp_t *time)
00038 {
00039 struct timeval tv;
00040 jiffies_to_timeval(jif, &tv);
00041 timeval_to_timestamp(&tv, time);
00042 }
00043
00044
00045
00046 int sim_daemon_radio_tx(struct sk_buff *skb,
00047 struct sk_buff_head *txq,
00048 struct sk_buff_head *multiplexq)
00049 {
00050 int error = 0;
00051 radio_t *radio = netdev_priv(skb->dev);
00052 unsigned int i, array_size = 0;
00053 unsigned int node_id = (unsigned int)radio->domid;
00054 struct divert_hdr *div_hdr;
00055 u32 *destinations;
00056 timestamp_t timestamp = 0;
00057 unsigned int duration = 0;
00058
00059 struct iphdr *iph = NULL;
00060 struct rtable **rts = NULL;
00061 u8 tos = 0;
00062 u16 df = 0;
00063 struct sock *sk = NULL;
00064
00065 DECLARE_WAITQUEUE(waitqueue, current);
00066 struct oq_req_resp *req;
00067 struct oq_req_resp *resp;
00068
00069 if (down_interruptible(&req_resp_lists->simd_sem)) {
00070 skb_queue_head(txq, skb);
00071 return -1;
00072 }
00073
00074 req = new_request("radio", node_id, -1,
00075 skb->data, jiffies);
00076 list_add_tail(&req->list,
00077 &req_resp_lists->request_list);
00078 wake_up_interruptible(&req_resp_lists->request_wait);
00079
00080 add_wait_queue(&req_resp_lists->response_wait,
00081 &waitqueue);
00082 set_current_state(TASK_INTERRUPTIBLE);
00083 while (list_empty(&req_resp_lists->response_list)) {
00084 up(&req_resp_lists->simd_sem);
00085
00086 schedule();
00087
00088 if (signal_pending(current))
00089 return -1;
00090 if (down_interruptible(&req_resp_lists->simd_sem))
00091 return -1;
00092 }
00093
00094 if (list_empty(&req_resp_lists->response_list)) {
00095 skb_queue_head(txq, skb);
00096 return -1;
00097 }
00098 __set_current_state(TASK_RUNNING);
00099 remove_wait_queue(&req_resp_lists->response_wait,
00100 &waitqueue);
00101
00102 resp = list_entry(&req_resp_lists->response_list,
00103 struct oq_req_resp, list);
00104 list_del(&resp->list);
00105
00110 destinations = (u32 *) kmalloc(sizeof(u32) * array_size, GFP_KERNEL);
00111 rts = (struct rtable**) kmalloc(sizeof(struct rtable *) * array_size,
00112 GFP_KERNEL);
00113 for (i = 0; i < array_size; i++)
00114 rts[i] = (struct rtable *) kmalloc(sizeof(struct rtable),
00115 GFP_KERNEL);
00116
00117
00118
00119 div_hdr = (struct divert_hdr *) skb_push(skb,
00120 sizeof(struct divert_hdr));
00121 div_hdr->collide = 0;
00122 div_hdr->initial = timestamp;
00123 div_hdr->duration = duration;
00124
00125
00126 for (i = 0; i < array_size; i++)
00127 ip_route_connect(&rts[i], destinations[i],
00128 inet_select_addr(skb->dev, 0, RT_SCOPE_LINK),
00129 0, 0, IPPROTO_TCP, PORT, PORT, sk);
00130
00131
00132 skb->h.raw = skb->nh.raw;
00133 skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
00134 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
00135 IPCB(skb)->flags &= ~(IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
00136 dst_release(skb->dst);
00137
00138
00139 iph = skb->nh.iph;
00140 iph->version = 4;
00141 iph->ihl = sizeof(struct iphdr) >> 2;
00142 iph->frag_off = df;
00143 iph->protocol = IPPROTO_OQIP;
00144 iph->tos = INET_ECN_encapsulate(tos, iph->tos);
00145 nf_reset(skb);
00146
00147
00148 for (i = 0; i < array_size; i++) {
00149 struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
00150 nskb->nh.iph->daddr = rts[i]->rt_dst;
00151 nskb->nh.iph->daddr = rts[i]->rt_src;
00152 nskb->dst = &rts[i]->u.dst;
00153
00154 skb_queue_tail(multiplexq, nskb);
00155 }
00156
00157 dev_kfree_skb(skb);
00158 kfree(destinations);
00159 for (i = 0; i < array_size; i++)
00160 kfree(rts[i]);
00161 kfree(rts);
00162 return error;
00163 }