new retransmit part 2
[cor_2_6_31.git] / net / cor / neighbor.c
blob4d4787adbc62da7d3bd41284cd9b8d4f581a0d97
1 /*
2 * Connection oriented routing
3 * Copyright (C) 2007-2009 Michael Blizek
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
21 #include "cor.h"
23 /**
24 * Splited packet data format:
25 * announce proto version [4]
26 * is 0, may be increased if format changes
27 * packet version [4]
28 * starts with 0, increments every time the data field changes
29 * total size [4]
30 * total data size of all merged packets
31 * offset [4]
32 * used to determine the order when merging the split packet
33 * unit is bytes
34 * [data]
35 * commulative checksum [8] (not yet)
36 * chunk 1 contains the checksum of the data in chunk 1
37 * chunk 2 contains the checksum of the data in chunk 1+2
38 * ...
40 * Data format of the announce packet "data" field:
41 * min_announce_proto_version [4]
42 * max_announce_proto_version [4]
43 * min_cor_proto_version [4]
44 * max_cor_proto_version [4]
45 * versions which are understood
47 * command [4]
48 * commandlength [4]
49 * commanddata [commandlength]
52 /* Commands */
54 #define NEIGHCMD_ADDADDR 1
56 /**
57 * Parameter:
58 * addrtypelen [2]
59 * addrtype [addrtypelen]
60 * addrlen [2]
61 * addr [addrlen]
65 DEFINE_MUTEX(neighbor_operation_lock);
67 char *addrtype = "id";
68 char *addr;
69 int addrlen;
72 LIST_HEAD(nb_list);
73 struct kmem_cache *nb_slab;
75 LIST_HEAD(announce_out_list);
77 struct notifier_block netdev_notify;
80 #define ADDRTYPE_UNKNOWN 0
81 #define ADDRTYPE_ID 1
83 static int get_addrtype(__u32 addrtypelen, char *addrtype)
85 if (addrtypelen == 2 &&
86 (addrtype[0] == 'i' || addrtype[0] == 'I') &&
87 (addrtype[1] == 'd' || addrtype[1] == 'D'))
88 return ADDRTYPE_ID;
90 return ADDRTYPE_UNKNOWN;
93 void neighbor_free(struct kref *ref)
95 struct neighbor *nb = container_of(ref, struct neighbor, ref);
96 printk(KERN_ERR "neighbor free");
97 BUG_ON(nb->nb_list.next != LIST_POISON1);
98 BUG_ON(nb->nb_list.prev != LIST_POISON2);
99 if (nb->addr != 0)
100 kfree(nb->addr);
101 nb->addr = 0;
102 if (nb->dev != 0)
103 dev_put(nb->dev);
104 nb->dev = 0;
105 kmem_cache_free(nb_slab, nb);
108 static struct neighbor *alloc_neighbor(gfp_t allocflags)
110 struct neighbor *nb = kmem_cache_alloc(nb_slab, allocflags);
111 __u32 seqno;
113 if (unlikely(nb == 0))
114 return 0;
116 memset(nb, 0, sizeof(struct neighbor));
118 kref_init(&(nb->ref));
119 mutex_init(&(nb->cmsg_lock));
120 INIT_LIST_HEAD(&(nb->control_msgs_out));
121 INIT_LIST_HEAD(&(nb->ucontrol_msgs_out));
122 nb->last_ping_time = jiffies;
123 atomic_set(&(nb->ooo_packets), 0);
124 get_random_bytes((char *) &seqno, sizeof(seqno));
125 mutex_init(&(nb->pingcookie_lock));
126 atomic_set(&(nb->latency), 0);
127 spin_lock_init(&(nb->state_lock));
128 atomic_set(&(nb->kpacket_seqno), seqno);
129 mutex_init(&(nb->conn_list_lock));
130 INIT_LIST_HEAD(&(nb->rcv_conn_list));
131 INIT_LIST_HEAD(&(nb->snd_conn_list));
132 spin_lock_init(&(nb->retrans_lock));
133 INIT_LIST_HEAD(&(nb->retrans_list));
134 INIT_LIST_HEAD(&(nb->retrans_list_conn));
136 return nb;
139 struct neighbor *get_neigh_by_mac(struct sk_buff *skb)
141 struct list_head *currlh;
142 struct neighbor *ret = 0;
145 char source_hw[MAX_ADDR_LEN];
146 memset(source_hw, 0, MAX_ADDR_LEN);
147 if (skb->dev->header_ops != 0 &&
148 skb->dev->header_ops->parse != 0)
149 skb->dev->header_ops->parse(skb, source_hw);
151 mutex_lock(&(neighbor_operation_lock));
153 currlh = nb_list.next;
155 while (currlh != &nb_list) {
156 struct neighbor *curr = container_of(currlh, struct neighbor,
157 nb_list);
159 if (memcmp(curr->mac, source_hw, MAX_ADDR_LEN) == 0) {
160 ret = curr;
161 kref_get(&(ret->ref));
162 break;
165 currlh = currlh->next;
168 mutex_unlock(&(neighbor_operation_lock));
170 return ret;
173 struct neighbor *find_neigh(__u16 addrtypelen, __u8 *addrtype,
174 __u16 addrlen, __u8 *addr)
176 struct list_head *currlh;
177 struct neighbor *ret = 0;
179 if (get_addrtype(addrtypelen, addrtype) != ADDRTYPE_ID)
180 return 0;
182 mutex_lock(&(neighbor_operation_lock));
184 currlh = nb_list.next;
186 while (currlh != &nb_list) {
187 struct neighbor *curr = container_of(currlh, struct neighbor,
188 nb_list);
190 if (curr->addrlen == addrlen && memcmp(curr->addr, addr,
191 addrlen) == 0) {
192 ret = curr;
193 kref_get(&(ret->ref));
195 goto out;
198 currlh = currlh->next;
201 out:
202 mutex_unlock(&(neighbor_operation_lock));
204 return ret;
207 __u32 generate_neigh_list(char *buf, __u32 buflen, __u32 limit, __u32 offset)
209 struct list_head *currlh;
211 char *p_totalneighs = buf;
212 char *p_response_rows = buf + 4;
214 int bufferfull = 0;
216 __u32 total = 0;
217 __u32 cnt = 0;
219 __u32 buf_offset = 8;
221 BUG_ON(buf == 0);
222 BUG_ON(buflen < 8);
224 mutex_lock(&(neighbor_operation_lock));
226 currlh = nb_list.next;
228 while (currlh != &nb_list) {
229 struct neighbor *curr = container_of(currlh, struct neighbor,
230 nb_list);
232 __u8 state;
233 unsigned long iflags;
234 /* get_neigh_state not used here because it would deadlock */
235 spin_lock_irqsave( &(curr->state_lock), iflags );
236 state = curr->state;
237 spin_unlock_irqrestore( &(curr->state_lock), iflags );
239 if (state != NEIGHBOR_STATE_ACTIVE)
240 goto cont2;
242 if (total < offset)
243 goto cont;
245 if (unlikely(buflen - buf_offset - 6 - 2 - curr->addrlen < 0))
246 bufferfull = 1;
248 if (bufferfull)
249 goto cont;
251 put_u16(buf + buf_offset, 1, 1);/* numaddr */
252 buf_offset += 2;
253 put_u16(buf + buf_offset, 2, 1);/* addrtypelen */
254 buf_offset += 2;
255 put_u16(buf + buf_offset, curr->addrlen, 1);/* addren */
256 buf_offset += 2;
257 buf[buf_offset] = 'i'; /* addrtype */
258 buf_offset += 1;
259 buf[buf_offset] = 'd';
260 buf_offset += 1;
261 memcpy(buf + buf_offset, curr->addr, curr->addrlen); /* addr */
262 buf_offset += curr->addrlen;
264 BUG_ON(buf_offset > buflen);
266 cnt++;
268 cont:
269 total++;
270 cont2:
271 currlh = currlh->next;
274 mutex_unlock(&(neighbor_operation_lock));
276 put_u32(p_totalneighs, total, 1);
277 put_u32(p_response_rows, cnt, 1);
279 return buf_offset;
282 void set_last_routdtrip(struct neighbor *nb, unsigned long time)
284 unsigned long iflags;
286 BUG_ON(nb == 0);
288 spin_lock_irqsave( &(nb->state_lock), iflags );
290 if(likely(nb->state == NEIGHBOR_STATE_ACTIVE) && time_after(time,
291 nb->state_time.last_roundtrip))
292 nb->state_time.last_roundtrip = time;
294 spin_unlock_irqrestore( &(nb->state_lock), iflags );
297 static void reset_stall_conns(struct neighbor *nb,
298 int stall_time_ms, int resetall)
300 struct list_head *currlh;
302 start:
303 mutex_lock(&(nb->conn_list_lock));
304 currlh = nb->snd_conn_list.next;
306 while (currlh != &(nb->snd_conn_list)) {
307 struct conn *rconn = container_of(currlh, struct conn,
308 target.out.nb_list);
309 BUG_ON(rconn->targettype != TARGET_OUT);
311 if (resetall || stall_time_ms >=
312 rconn->target.out.stall_timeout_ms) {
314 * reset_conn must not be called with conn_list_lock
315 * held
317 mutex_unlock(&(nb->conn_list_lock));
318 reset_conn(rconn);
319 goto start;
321 currlh = currlh->next;
323 mutex_unlock(&(nb->conn_list_lock));
326 static void stall_timerfunc(struct work_struct *work);
328 static void stall_timer(struct neighbor *nb, int fromtimer)
330 int stall_time_ms;
331 __u8 nbstate;
333 int resetall;
335 unsigned long iflags;
337 spin_lock_irqsave( &(nb->state_lock), iflags );
338 stall_time_ms = jiffies_to_msecs(jiffies -
339 nb->state_time.last_roundtrip);
340 nbstate = nb->state;
342 if (unlikely(nbstate != NEIGHBOR_STATE_STALLED))
343 nb->str_timer_pending = 0;
344 spin_unlock_irqrestore( &(nb->state_lock), iflags );
346 if (unlikely(nbstate != NEIGHBOR_STATE_STALLED)) {
347 kref_put(&(nb->ref), neighbor_free);
348 return;
351 resetall = (stall_time_ms > NB_KILL_TIME_MS);
353 /*if(resetall)
354 printk(KERN_ERR "reset_all");*/
356 reset_stall_conns(nb, stall_time_ms, resetall);
358 if (resetall) {
359 spin_lock_irqsave( &(nb->state_lock), iflags );
360 nb->state = NEIGHBOR_STATE_KILLED;
361 spin_unlock_irqrestore( &(nb->state_lock), iflags );
363 list_del(&(nb->nb_list));
364 kref_put(&(nb->ref), neighbor_free); /* nb_list */
366 kref_put(&(nb->ref), neighbor_free); /* stall_timer */
368 } else {
369 if (fromtimer == 0) {
370 int pending;
371 spin_lock_irqsave( &(nb->state_lock), iflags );
372 pending = nb->str_timer_pending;
373 spin_unlock_irqrestore( &(nb->state_lock), iflags );
375 if (pending)
376 return;
378 kref_get(&(nb->ref));
381 INIT_DELAYED_WORK(&(nb->stalltimeout_timer), stall_timerfunc);
382 schedule_delayed_work(&(nb->stalltimeout_timer),
383 msecs_to_jiffies(STALL_TIMER_INTERVAL_MS));
387 static void stall_timerfunc(struct work_struct *work)
389 struct neighbor *nb = container_of(to_delayed_work(work),
390 struct neighbor, stalltimeout_timer);
391 stall_timer(nb, 1);
395 int get_neigh_state(struct neighbor *nb)
397 int ret;
398 int switchedtostalled = 0;
399 unsigned long iflags;
401 BUG_ON(nb == 0);
403 spin_lock_irqsave( &(nb->state_lock), iflags );
405 if (unlikely(likely(nb->state == NEIGHBOR_STATE_ACTIVE) && unlikely(
406 time_after_eq(jiffies, nb->state_time.last_roundtrip +
407 msecs_to_jiffies(NB_STALL_TIME_MS))))) {
408 nb->state = NEIGHBOR_STATE_STALLED;
409 switchedtostalled = 1;
412 ret = nb->state;
414 spin_unlock_irqrestore( &(nb->state_lock), iflags );
416 if (unlikely(switchedtostalled)) {
417 /*printk(KERN_ERR "switched to stalled");*/
418 stall_timer(nb, 0);
421 return ret;
424 static struct ping_cookie *find_cookie(struct neighbor *nb, __u32 cookie)
426 int i;
428 for(i=0;i<PING_COOKIES_PER_NEIGH;i++) {
429 if (nb->cookies[i].cookie == cookie)
430 return &(nb->cookies[i]);
432 return 0;
435 void ping_resp(struct neighbor *nb, __u32 cookie, __u32 respdelay)
437 struct ping_cookie *c;
438 int i;
440 unsigned long cookie_sendtime;
441 __s64 newlatency;
443 unsigned long iflags;
445 mutex_lock(&(nb->pingcookie_lock));
447 c = find_cookie(nb, cookie);
449 if (unlikely(c == 0))
450 goto out;
452 cookie_sendtime = c->time;
454 newlatency = ((((__s64) ((__u32)atomic_read(&(nb->latency)))) * 15 +
455 jiffies_to_usecs(jiffies - c->time) - respdelay) / 16);
456 if (unlikely(newlatency < 0))
457 newlatency = 0;
458 if (unlikely(newlatency > (((__s64)256)*256*256*256 - 1)))
459 newlatency = ((__s64)256)*256*256*256 - 1;
461 atomic_set(&(nb->latency), (__u32) newlatency);
463 c->cookie = 0;
464 nb->ping_intransit--;
466 for(i=0;i<PING_COOKIES_PER_NEIGH;i++) {
467 if (nb->cookies[i].cookie != 0 &&
468 time_before(nb->cookies[i].time, c->time)) {
469 nb->cookies[i].pongs++;
470 if (nb->cookies[i].pongs >= PING_PONGLIMIT) {
471 nb->cookies[i].cookie = 0;
472 nb->cookies[i].pongs = 0;
473 nb->ping_intransit--;
478 spin_lock_irqsave( &(nb->state_lock), iflags );
480 if (unlikely(nb->state == NEIGHBOR_STATE_INITIAL ||
481 nb->state == NEIGHBOR_STATE_STALLED)) {
482 nb->ping_success++;
484 if (nb->state == NEIGHBOR_STATE_INITIAL) {
485 __u64 jiffies64 = get_jiffies_64();
486 if (nb->state_time.last_state_change == 0)
487 nb->state_time.last_state_change = jiffies64;
488 if (jiffies64 <= (nb->state_time.last_state_change +
489 msecs_to_jiffies(INITIAL_TIME_MS)))
490 goto out2;
493 if (nb->ping_success >= PING_SUCCESS_CNT) {
494 /*if (nb->state == NEIGHBOR_STATE_INITIAL)
495 printk(KERN_ERR "switched from initial to active");
496 else
497 printk(KERN_ERR "switched from stalled to active");
499 nb->state = NEIGHBOR_STATE_ACTIVE;
500 nb->ping_success = 0;
501 nb->state_time.last_roundtrip = jiffies;
503 } else {
504 nb->state_time.last_roundtrip = cookie_sendtime;
507 out2:
508 spin_unlock_irqrestore( &(nb->state_lock), iflags );
510 out:
511 mutex_unlock(&(nb->pingcookie_lock));
514 __u32 add_ping_req(struct neighbor *nb)
516 struct ping_cookie *c;
517 __u32 i;
519 __u32 cookie;
521 mutex_lock(&(nb->pingcookie_lock));
523 for (i=0;i<PING_COOKIES_PER_NEIGH;i++) {
524 if (nb->cookies[i].cookie == 0)
525 goto found;
528 get_random_bytes((char *) &i, sizeof(i));
529 i = (i % (PING_COOKIES_PER_NEIGH - PING_COOKIES_FIFO)) +
530 PING_COOKIES_FIFO;
532 found:
533 c = &(nb->cookies[i]);
534 c->time = jiffies;
535 c->pongs = 0;
536 nb->lastcookie++;
537 if (unlikely(nb->lastcookie == 0))
538 nb->lastcookie++;
539 c->cookie = nb->lastcookie;
541 nb->ping_intransit++;
543 cookie = c->cookie;
545 mutex_unlock(&(nb->pingcookie_lock));
547 return cookie;
552 * Check additional to the checks and timings already done in kpacket_gen.c
553 * This is primarily to make sure that we do not invalidate other ping cookies
554 * which might still receive responses. It does this by requiring a certain
555 * mimimum delay between pings, depending on how many pings are already in
556 * transit.
558 int time_to_send_ping(struct neighbor *nb)
560 int rc = 1;
562 mutex_lock(&(nb->pingcookie_lock));
563 if (nb->ping_intransit >= PING_COOKIES_NOTHROTTLE) {
564 __u32 mindelay = (((__u32)atomic_read(&(nb->latency)))/1000) <<
565 (nb->ping_intransit + 1 -
566 PING_COOKIES_NOTHROTTLE);
567 if (mindelay > PING_THROTTLE_LIMIT_MS)
568 mindelay = PING_THROTTLE_LIMIT_MS;
570 if (jiffies_to_msecs(jiffies - nb->last_ping_time) < mindelay)
571 rc = 0;
573 mutex_unlock(&(nb->pingcookie_lock));
575 return rc;
578 static void add_neighbor(struct neighbor *nb)
580 struct list_head *currlh = nb_list.next;
582 BUG_ON((nb->addr == 0) != (nb->addrlen == 0));
584 while (currlh != &nb_list) {
585 struct neighbor *curr = container_of(currlh, struct neighbor,
586 nb_list);
588 if (curr->addrlen == nb->addrlen && memcmp(curr->addr, nb->addr,
589 curr->addrlen) == 0)
590 goto already_present;
592 currlh = currlh->next;
594 /* kref_get not needed here, because the caller leaves its ref to us */
595 printk(KERN_ERR "add_neigh");
596 list_add_tail(&(nb->nb_list), &nb_list);
597 schedule_controlmsg_timerfunc(nb);
598 setup_timer(&(nb->retrans_timer), retransmit_timerfunc,
599 (unsigned long) nb);
600 INIT_DELAYED_WORK(&(nb->retrans_timer_conn), retransmit_conn_timerfunc);
602 if (0) {
603 already_present:
604 kmem_cache_free(nb_slab, nb);
608 static __u32 pull_u32(struct sk_buff *skb, int convbo)
610 char *ptr = cor_pull_skb(skb, 4);
612 __u32 ret = 0;
614 BUG_ON(0 == ptr);
616 ((char *)&ret)[0] = ptr[0];
617 ((char *)&ret)[1] = ptr[1];
618 ((char *)&ret)[2] = ptr[2];
619 ((char *)&ret)[3] = ptr[3];
621 if (convbo)
622 return be32_to_cpu(ret);
623 return ret;
626 static int apply_announce_addaddr(struct neighbor *nb, __u32 cmd, __u32 len,
627 char *cmddata)
629 __u16 addrtypelen;
630 char *addrtype;
631 __u16 addrlen;
632 char *addr;
634 BUG_ON((nb->addr == 0) != (nb->addrlen == 0));
636 if (nb->addr != 0)
637 return 0;
639 if (len < 4)
640 return 0;
642 addrtypelen = be16_to_cpu(*((__u16 *) cmddata));
643 cmddata += 2;
644 len -= 2;
646 if (len < 2)
647 return 0;
649 addrlen = be16_to_cpu(*((__u16 *) cmddata));
650 cmddata += 2;
651 len -= 2;
653 addrtype = cmddata;
654 cmddata += addrtypelen;
655 len -= addrtypelen;
657 addr = cmddata;
658 cmddata += addrlen;
659 len -= addrlen;
661 if (len < 0)
662 return 0;
664 if (get_addrtype(addrtypelen, addrtype) != ADDRTYPE_ID)
665 return 0;
667 nb->addr = kmalloc(addrlen, GFP_KERNEL);
668 if (unlikely(nb->addr == 0))
669 return 1;
671 memcpy(nb->addr, addr, addrlen);
672 nb->addrlen = addrlen;
674 return 0;
677 static void apply_announce_cmd(struct neighbor *nb, __u32 cmd, __u32 len,
678 char *cmddata)
680 if (cmd == NEIGHCMD_ADDADDR) {
681 apply_announce_addaddr(nb, cmd, len, cmddata);
682 } else {
683 /* ignore unknown cmds */
687 static void apply_announce_cmds(char *msg, __u32 len, struct net_device *dev,
688 char *source_hw)
690 struct neighbor *nb = alloc_neighbor(GFP_KERNEL);
692 if (unlikely(nb == 0))
693 return;
695 while (len >= 8) {
696 __u32 cmd;
697 __u32 cmdlen;
699 cmd = be32_to_cpu(*((__u32 *) msg));
700 msg += 4;
701 len -= 4;
702 cmdlen = be32_to_cpu(*((__u32 *) msg));
703 msg += 4;
704 len -= 4;
706 BUG_ON(cmdlen > len);
708 apply_announce_cmd(nb, cmd, cmdlen, msg);
710 msg += cmdlen;
711 len -= cmdlen;
714 BUG_ON(len != 0);
716 memcpy(nb->mac, source_hw, MAX_ADDR_LEN);
718 dev_hold(dev);
719 nb->dev = dev;
720 add_neighbor(nb);
723 static int check_announce_cmds(char *msg, __u32 len)
725 while (len >= 8) {
726 __u32 cmd;
727 __u32 cmdlen;
729 cmd = be32_to_cpu(*((__u32 *) msg));
730 msg += 4;
731 len -= 4;
732 cmdlen = be32_to_cpu(*((__u32 *) msg));
733 msg += 4;
734 len -= 4;
736 /* malformated packet */
737 if (unlikely(cmdlen > len))
738 return 1;
740 msg += cmdlen;
741 len -= cmdlen;
744 if (unlikely(len != 0))
745 return 1;
747 return 0;
750 static void parse_announce(char *msg, __u32 len, struct net_device *dev,
751 char *source_hw)
753 __u32 min_announce_version;
754 __u32 max_announce_version;
755 __u32 min_cor_version;
756 __u32 max_cor_version;
758 if (unlikely(len < 16))
759 return;
761 min_announce_version = be32_to_cpu(*((__u32 *) msg));
762 msg += 4;
763 len -= 4;
764 max_announce_version = be32_to_cpu(*((__u32 *) msg));
765 msg += 4;
766 len -= 4;
767 min_cor_version = be32_to_cpu(*((__u32 *) msg));
768 msg += 4;
769 len -= 4;
770 max_cor_version = be32_to_cpu(*((__u32 *) msg));
771 msg += 4;
772 len -= 4;
774 if (min_announce_version != 0)
775 return;
776 if (min_cor_version != 0)
777 return;
778 if (check_announce_cmds(msg, len)) {
779 return;
781 apply_announce_cmds(msg, len, dev, source_hw);
784 struct announce_in {
785 /* lh has to be first */
786 struct list_head lh;
787 struct sk_buff_head skbs; /* sorted by offset */
788 struct net_device *dev;
789 char source_hw[MAX_ADDR_LEN];
790 __u32 announce_proto_version;
791 __u32 packet_version;
792 __u32 total_size;
793 __u32 received_size;
794 __u64 last_received_packet;
797 LIST_HEAD(announce_list);
799 struct kmem_cache *announce_in_slab;
801 static void merge_announce(struct announce_in *ann)
803 char *msg = kmalloc(ann->total_size, GFP_KERNEL);
804 __u32 copy = 0;
806 if (msg == 0) {
807 /* try again when next packet arrives */
808 return;
811 while (copy != ann->total_size) {
812 __u32 currcpy;
813 __u32 offset = 0;
814 struct sk_buff *skb;
815 struct skb_procstate *ps;
817 if (unlikely(skb_queue_empty(&(ann->skbs)))) {
818 printk(KERN_ERR "net/cor/neighbor.c: sk_head ran "
819 "empty while merging packets\n");
820 goto free;
823 skb = skb_dequeue(&(ann->skbs));
824 ps = skb_pstate(skb);
826 currcpy = skb->len;
827 if (unlikely(ps->funcstate.announce.offset > copy)) {
828 printk(KERN_ERR "net/cor/neighbor.c: invalid offset"
829 "value found\n");
830 goto free;
833 if (unlikely(ps->funcstate.announce.offset < copy)) {
834 offset = copy - ps->funcstate.announce.offset;
835 currcpy -= offset;
838 if (unlikely(currcpy + copy > ann->total_size))
839 goto free;
841 memcpy(msg + copy, skb->data + offset, currcpy);
842 copy += currcpy;
843 kfree_skb(skb);
846 parse_announce(msg, ann->total_size, ann->dev, ann->source_hw);
848 free:
849 if (msg != 0)
850 kfree(msg);
852 dev_put(ann->dev);
853 list_del(&(ann->lh));
854 kmem_cache_free(announce_in_slab, ann);
857 static int _rcv_announce(struct sk_buff *skb, struct announce_in *ann)
859 struct skb_procstate *ps = skb_pstate(skb);
861 __u32 offset = ps->funcstate.announce.offset;
862 __u32 len = skb->len;
864 __u32 curroffset = 0;
865 __u32 prevoffset = 0;
866 __u32 prevlen = 0;
868 struct sk_buff *curr = ann->skbs.next;
870 if (unlikely(len + offset > ann->total_size)) {
871 /* invalid header */
872 kfree_skb(skb);
873 return 0;
877 * Try to find the right place to insert in the sorted list. This
878 * means to process the list until we find a skb which has a greater
879 * offset, so we can insert before it to keep the sort order. However,
880 * this is complicated by the fact that the new skb must not be inserted
881 * between 2 skbs if there is no data missing in between. So the loop
882 * runs has to keep running until there is either a gap to insert or
883 * we see that this data has already been received.
885 while ((void *) curr != (void *) &(ann->skbs)) {
886 struct skb_procstate *currps = skb_pstate(skb);
888 curroffset = currps->funcstate.announce.offset;
890 if (curroffset > offset && (prevoffset + prevlen) < curroffset)
891 break;
893 prevoffset = curroffset;
894 prevlen = curr->len;
895 curr = curr->next;
897 if ((offset+len) <= (prevoffset+prevlen)) {
898 /* we already have this data */
899 kfree_skb(skb);
900 return 0;
905 * Calculate how much data was really received, by substracting
906 * the bytes we already have.
908 if (unlikely(prevoffset + prevlen > offset)) {
909 len -= (prevoffset + prevlen) - offset;
910 offset = prevoffset + prevlen;
913 if (unlikely((void *) curr != (void *) &(ann->skbs) &&
914 (offset + len) > curroffset))
915 len = curroffset - offset;
917 ann->received_size += len;
918 BUG_ON(ann->received_size > ann->total_size);
919 __skb_queue_before(&(ann->skbs), curr, skb);
920 ann->last_received_packet = get_jiffies_64();
922 if (ann->received_size == ann->total_size)
923 merge_announce(ann);
924 else if (unlikely(ann->skbs.qlen >= 16))
925 return 1;
927 return 0;
930 void rcv_announce(struct sk_buff *skb)
932 struct skb_procstate *ps = skb_pstate(skb);
933 struct announce_in *curr = 0;
934 struct announce_in *leastactive = 0;
935 __u32 list_size = 0;
937 __u32 announce_proto_version = pull_u32(skb, 1);
938 __u32 packet_version = pull_u32(skb, 1);
939 __u32 total_size = pull_u32(skb, 1);
941 char source_hw[MAX_ADDR_LEN];
942 memset(source_hw, 0, MAX_ADDR_LEN);
943 if (skb->dev->header_ops != 0 &&
944 skb->dev->header_ops->parse != 0)
945 skb->dev->header_ops->parse(skb, source_hw);
947 ps->funcstate.announce.offset = pull_u32(skb, 1);
949 if (total_size > 8192)
950 goto discard;
952 mutex_lock(&(neighbor_operation_lock));
954 if (announce_proto_version != 0)
955 goto discard;
957 curr = (struct announce_in *) announce_list.next;
959 while (((struct list_head *) curr) != &(announce_list)) {
960 list_size++;
961 if (curr->dev == skb->dev &&
962 memcmp(curr->source_hw, source_hw, MAX_ADDR_LEN) == 0 &&
963 curr->announce_proto_version == announce_proto_version &&
964 curr->packet_version == packet_version &&
965 curr->total_size == total_size)
966 goto found;
968 if (leastactive == 0 || curr->last_received_packet <
969 leastactive->last_received_packet)
970 leastactive = curr;
972 curr = (struct announce_in *) curr->lh.next;
975 if (list_size >= 128) {
976 BUG_ON(leastactive == 0);
977 curr = leastactive;
979 curr->last_received_packet = get_jiffies_64();
981 while (!skb_queue_empty(&(curr->skbs))) {
982 struct sk_buff *skb2 = skb_dequeue(&(curr->skbs));
983 kfree_skb(skb2);
986 dev_put(curr->dev);
987 } else {
988 curr = kmem_cache_alloc(announce_in_slab,
989 GFP_KERNEL);
990 if (curr == 0)
991 goto discard;
993 skb_queue_head_init(&(curr->skbs));
994 list_add_tail((struct list_head *) curr, &announce_list);
997 curr->packet_version = packet_version;
998 curr->total_size = total_size;
999 curr->received_size = 0;
1000 curr->announce_proto_version = announce_proto_version;
1001 curr->dev = skb->dev;
1002 dev_hold(curr->dev);
1003 memcpy(curr->source_hw, source_hw, MAX_ADDR_LEN);
1005 found:
1006 if (_rcv_announce(skb, curr)) {
1007 list_del((struct list_head *) curr);
1008 dev_put(curr->dev);
1009 kmem_cache_free(announce_in_slab, curr);
1012 if (0) {
1013 discard:
1014 kfree_skb(skb);
1017 mutex_unlock(&(neighbor_operation_lock));
1020 struct announce {
1021 struct kref ref;
1023 __u32 packet_version;
1024 char *announce_msg;
1025 __u32 announce_msg_len;
1028 struct announce *last_announce;
1030 struct announce_data {
1031 struct delayed_work announce_work;
1033 struct net_device *dev;
1035 struct announce *ann;
1037 struct list_head lh;
1039 __u32 curr_announce_msg_offset;
1040 __u64 scheduled_announce_timer;
1043 static void _splitsend_announce(struct announce_data *ann)
1045 struct sk_buff *skb;
1046 __u32 packet_size = 256;
1047 __u32 remainingdata = ann->ann->announce_msg_len -
1048 ann->curr_announce_msg_offset;
1049 __u32 headroom = LL_ALLOCATED_SPACE(ann->dev);
1050 __u32 overhead = 17 + headroom;
1051 char *header;
1052 char *ptr;
1054 if (remainingdata < packet_size)
1055 packet_size = remainingdata;
1057 skb = alloc_skb(packet_size + overhead, GFP_KERNEL);
1058 if (unlikely(0 == skb))
1059 return;
1061 skb->protocol = htons(ETH_P_COR);
1062 skb->dev = ann->dev;
1063 skb_reserve(skb, headroom);
1065 if(unlikely(dev_hard_header(skb, ann->dev, ETH_P_COR,
1066 ann->dev->broadcast, ann->dev->dev_addr, skb->len) < 0))
1067 goto out_err;
1069 skb_reset_network_header(skb);
1071 header = skb_put(skb, 17);
1072 if (unlikely(header == 0))
1073 goto out_err;
1075 header[0] = PACKET_TYPE_ANNOUNCE;
1077 put_u32(header + 1, 0, 1); /* announce proto version */
1078 put_u32(header + 5, ann->ann->packet_version, 1); /* packet version */
1079 put_u32(header + 9, ann->ann->announce_msg_len, 1); /* total size */
1080 put_u32(header + 13, ann->curr_announce_msg_offset, 1); /* offset */
1082 ptr = skb_put(skb, packet_size);
1083 if (unlikely(ptr == 0))
1084 goto out_err;
1086 memcpy(ptr, ann->ann->announce_msg + ann->curr_announce_msg_offset, packet_size);
1087 dev_queue_xmit(skb);
1089 ann->curr_announce_msg_offset += packet_size;
1091 if (ann->curr_announce_msg_offset == ann->ann->announce_msg_len)
1092 ann->curr_announce_msg_offset = 0;
1094 if (0) {
1095 out_err:
1096 if (skb != 0)
1097 kfree_skb(skb);
1101 static void announce_free(struct kref *ref)
1103 struct announce *ann = container_of(ref, struct announce, ref);
1104 kfree(&(ann->announce_msg));
1105 kfree(ann);
1108 static void splitsend_announce(struct work_struct *work)
1110 struct announce_data *ann = container_of(to_delayed_work(work),
1111 struct announce_data, announce_work);
1112 int reschedule = 0;
1114 mutex_lock(&(neighbor_operation_lock));
1116 if (unlikely(ann->dev == 0))
1117 goto out;
1119 reschedule = 1;
1121 if (unlikely(ann->ann == 0 && last_announce == 0))
1122 goto out;
1124 if (ann->curr_announce_msg_offset == 0 &&
1125 unlikely(ann->ann != last_announce)) {
1126 if (ann->ann != 0)
1127 kref_put(&(ann->ann->ref), announce_free);
1128 ann->ann = last_announce;
1129 kref_get(&(ann->ann->ref));
1132 _splitsend_announce(ann);
1133 out:
1134 mutex_unlock(&(neighbor_operation_lock));
1136 if (reschedule) {
1137 int target_delay_ms = 500;
1138 int target_delay_jiffies = msecs_to_jiffies(target_delay_ms);
1139 __u64 jiffies = get_jiffies_64();
1140 int delay;
1142 ann->scheduled_announce_timer += target_delay_jiffies;
1144 delay = ann->scheduled_announce_timer - jiffies;
1145 if (delay < 0)
1146 delay = 0;
1148 INIT_DELAYED_WORK(&(ann->announce_work), splitsend_announce);
1149 schedule_delayed_work(&(ann->announce_work), delay);
1153 static struct announce_data *get_announce_by_netdev(struct net_device *dev)
1155 struct list_head *lh = announce_out_list.next;
1157 while (lh != &announce_out_list) {
1158 struct announce_data *curr = (struct announce_data *)(
1159 ((char *) lh) -
1160 offsetof(struct announce_data, lh));
1162 if (curr->dev == dev)
1163 return curr;
1166 return 0;
1169 static void announce_sent_adddev(struct net_device *dev)
1171 struct announce_data *ann;
1173 ann = kmalloc(sizeof(struct announce_data), GFP_KERNEL);
1175 if (unlikely(ann == 0)) {
1176 printk(KERN_ERR "cor cannot allocate memory for sending "
1177 "announces");
1178 return;
1181 memset(ann, 0, sizeof(struct announce_data));
1183 dev_hold(dev);
1184 ann->dev = dev;
1186 mutex_lock(&(neighbor_operation_lock));
1187 list_add_tail(&(ann->lh), &announce_out_list);
1188 mutex_unlock(&(neighbor_operation_lock));
1190 ann->scheduled_announce_timer = get_jiffies_64();
1191 INIT_DELAYED_WORK(&(ann->announce_work), splitsend_announce);
1192 schedule_delayed_work(&(ann->announce_work), 1);
1195 static void announce_sent_rmdev(struct net_device *dev)
1197 struct announce_data *ann;
1199 mutex_lock(&(neighbor_operation_lock));
1201 ann = get_announce_by_netdev(dev);
1203 if (ann == 0)
1204 goto out;
1206 dev_put(ann->dev);
1207 ann->dev = 0;
1209 out:
1210 mutex_unlock(&(neighbor_operation_lock));
1213 int netdev_notify_func(struct notifier_block *not, unsigned long event,
1214 void *ptr)
1216 struct net_device *dev = (struct net_device *) ptr;
1218 switch(event){
1219 case NETDEV_UP:
1220 announce_sent_adddev(dev);
1221 break;
1222 case NETDEV_DOWN:
1223 announce_sent_rmdev(dev);
1224 break;
1225 case NETDEV_REBOOT:
1226 case NETDEV_CHANGE:
1227 case NETDEV_REGISTER:
1228 case NETDEV_UNREGISTER:
1229 case NETDEV_CHANGEMTU:
1230 case NETDEV_CHANGEADDR:
1231 case NETDEV_GOING_DOWN:
1232 case NETDEV_CHANGENAME:
1233 case NETDEV_FEAT_CHANGE:
1234 case NETDEV_BONDING_FAILOVER:
1235 break;
1236 default:
1237 return 1;
1240 return 0;
1243 static int set_announce(char *msg, __u32 len)
1245 struct announce *ann = kmalloc(sizeof(struct announce), GFP_KERNEL);
1247 if (unlikely(ann == 0)) {
1248 kfree(msg);
1249 return 1;
1252 memset(ann, 0, sizeof(struct announce));
1254 ann->announce_msg = msg;
1255 ann->announce_msg_len = len;
1257 kref_init(&(ann->ref));
1259 mutex_lock(&(neighbor_operation_lock));
1261 if (last_announce != 0) {
1262 ann->packet_version = last_announce->packet_version + 1;
1263 kref_put(&(last_announce->ref), announce_free);
1266 last_announce = ann;
1268 mutex_unlock(&(neighbor_operation_lock));
1270 return 0;
1273 static int generate_announce(void)
1275 __u32 addrtypelen = strlen(addrtype);
1277 __u32 hdr_len = 16;
1278 __u32 cmd_hdr_len = 8;
1279 __u32 cmd_len = 2 + 2 + addrtypelen + addrlen;
1281 __u32 len = hdr_len + cmd_hdr_len + cmd_len;
1282 __u32 offset = 0;
1284 char *msg = kmalloc(len, GFP_KERNEL);
1285 if (unlikely(msg == 0))
1286 return 1;
1288 put_u32(msg + offset, 0, 1); /* min_announce_proto_version */
1289 offset += 4;
1290 put_u32(msg + offset, 0, 1); /* max_announce_proto_version */
1291 offset += 4;
1292 put_u32(msg + offset, 0, 1); /* min_cor_proto_version */
1293 offset += 4;
1294 put_u32(msg + offset, 0, 1); /* max_cor_proto_version */
1295 offset += 4;
1298 put_u32(msg + offset, NEIGHCMD_ADDADDR, 1); /* command */
1299 offset += 4;
1300 put_u32(msg + offset, cmd_len, 1); /* command length */
1301 offset += 4;
1303 /* addrtypelen, addrlen */
1304 put_u16(msg + offset, addrtypelen, 1);
1305 offset += 2;
1306 put_u16(msg + offset, addrlen, 1);
1307 offset += 2;
1309 /* addrtype, addr */
1310 memcpy(msg + offset, addrtype, addrtypelen);
1311 offset += addrtypelen;
1312 memcpy(msg + offset, addr, addrlen);
1313 offset += addrlen;
1315 BUG_ON(offset != len);
1317 return set_announce(msg, len);
1320 int __init cor_neighbor_init(void)
1322 addrlen = 16;
1324 addr = kmalloc(addrlen, GFP_KERNEL);
1325 if (unlikely(addr == 0))
1326 goto error_free2;
1328 get_random_bytes(addr, addrlen);
1330 nb_slab = kmem_cache_create("cor_neighbor", sizeof(struct neighbor), 8,
1331 0, 0);
1332 announce_in_slab = kmem_cache_create("cor_announce_in",
1333 sizeof(struct announce_in), 8, 0, 0);
1335 if (unlikely(generate_announce()))
1336 goto error_free1;
1338 memset(&netdev_notify, 0, sizeof(netdev_notify));
1339 netdev_notify.notifier_call = netdev_notify_func;
1340 register_netdevice_notifier(&netdev_notify);
1342 return 0;
1344 error_free1:
1345 kfree(addr);
1347 error_free2:
1348 return -ENOMEM;
1351 MODULE_LICENSE("GPL");