4aebe5bc5316cd9e013e83dbbc080e85a1d1a04d
[linux-flexiantxendom0-3.2.10.git] / net / ipv6 / mobile_ip6 / mobhdr_mn.c
1 /*
2  *      Mobile IPv6 Mobility Header Functions for Mobile Node
3  *
4  *      Authors:
5  *      Antti Tuominen  <ajtuomin@tml.hut.fi>
6  *      Niklas Kämpe    <nhkampe@cc.hut.fi>
7  *      Henrik Petander <henrik.petander@hut.fi>
8  *
9  *      $Id:$
10  *
11  *      This program is free software; you can redistribute it and/or
12  *      modify it under the terms of the GNU General Public License as
13  *      published by the Free Software Foundation; either version 2 of
14  *      the License, or (at your option) any later version.
15  *
16  */
17
18 #include <linux/types.h>
19 #include <linux/sched.h>
20 #include <linux/init.h>
21 #include <net/ipv6.h>
22 #include <net/addrconf.h>
23 #include <net/mipv6.h>
24
25 #include "mobhdr.h"
26 #include "mn.h"
27 #include "bul.h"
28 #include "rr_crypto.h"
29 #include "debug.h"
30 #include "util.h"
31 #include "stats.h"
32
33 int rr_configured = 1;
34
35 /* Return value of mipv6_rr_state() */
36 #define NO_RR                   0
37 #define DO_RR                   1
38 #define RR_FOR_COA              2
39 #define INPROGRESS_RR           3
40
41 /** 
42  * send_bu_msg - sends a Binding Update 
43  * @bulentry : BUL entry with the information for building a BU
44  *
45  * Function builds a BU msg based on the contents of a bul entry.
46  * Does not change the bul entry.
47  **/
48 static int send_bu_msg(struct mipv6_bul_entry *binding)
49
50         int auth = 0; /* Use auth */
51         int ret = 0;
52         struct mipv6_auth_parm parm;
53         struct mipv6_mh_bu bu;
54
55         DEBUG_FUNC();
56
57         if (!binding) {
58                 DEBUG(DBG_ERROR, "called with a null bul entry");
59                 return -1;
60         }
61         
62         memset(&parm, 0, sizeof(parm));
63         if (mipv6_prefix_compare(&binding->coa, &binding->home_addr, 64))
64                 parm.coa = &binding->home_addr;
65         else
66                 parm.coa = &binding->coa;
67         parm.cn_addr = &binding->cn_addr;
68
69         if (binding->rr && binding->rr->kbu) {
70                 DEBUG(DBG_INFO, "Binding with key");
71                 auth = 1;
72                 parm.k_bu = binding->rr->kbu;
73         }
74         memset(&bu, 0, sizeof(bu));
75         bu.flags = binding->flags;
76         bu.sequence = htons(binding->seq);
77         bu.lifetime = htons(binding->lifetime >> 2);
78         bu.reserved = 0;
79
80         ret = send_mh(&binding->cn_addr, &binding->home_addr,
81                       MIPV6_MH_BU, sizeof(bu), (u8 *)&bu, 
82                       &binding->home_addr, NULL, 
83                       binding->ops, &parm);
84
85         if (ret == 0)
86                 MIPV6_INC_STATS(n_bu_sent);
87
88         return ret;
89 }
90
91 /**
92  * mipv6_send_addr_test_init - send a HoTI or CoTI message
93  * @saddr: source address for H/CoTI
94  * @daddr: destination address for H/CoTI
95  * @msg_type: Identifies whether HoTI or CoTI
96  * @init_cookie: the HoTi or CoTi init cookie
97  *
98  * The message will be retransmitted till we get a HoT or CoT message, since 
99  * our caller (mipv6_RR_start) has entered this message in the BUL with
100  * exponential backoff retramission set.
101  */
102 static int mipv6_send_addr_test_init(struct in6_addr *saddr,
103                                      struct in6_addr *daddr,
104                                      u8 msg_type,
105                                      u8 *init_cookie)
106 {
107         struct mipv6_mh_addr_ti ti;
108         struct mipv6_mh_opt *ops = NULL;
109         int ret = 0;
110
111         /* Set reserved and copy the cookie from address test init msg */
112         ti.reserved = 0;
113         memcpy(ti.init_cookie, init_cookie, MIPV6_RR_COOKIE_LENGTH);
114
115         ret = send_mh(daddr, saddr, msg_type, sizeof(ti), (u8 *)&ti,
116                       NULL, NULL, ops, NULL);
117         if (ret == 0) {
118                 if (msg_type == MIPV6_MH_HOTI) {
119                         MIPV6_INC_STATS(n_hoti_sent);
120                 } else {
121                         MIPV6_INC_STATS(n_coti_sent);
122                 }
123         }
124
125         return ret;
126 }
127
128 /*
129  *
130  * Callback handlers for binding update list
131  *
132  */
133
134 /* Return value 0 means keep entry, non-zero means discard entry. */
135
136 /* Callback for BUs not requiring acknowledgement
137  */
138 static int bul_expired(struct mipv6_bul_entry *bulentry)
139 {
140         /* Lifetime expired, delete entry. */
141         DEBUG(DBG_INFO, "bul entry 0x%x lifetime expired, deleting entry", (int) bulentry);
142         return 1;
143 }
144
145 /* Callback for BUs requiring acknowledgement with exponential resending
146  * scheme */
147 static int bul_resend_exp(struct mipv6_bul_entry *bulentry)
148 {
149         unsigned long now = jiffies;
150         
151         DEBUG(DBG_INFO, "(0x%x) resending bu", (int) bulentry);
152
153         
154         /* If sending a de-registration, do not care about the
155          * lifetime value, as de-registrations are normally sent with
156          * a zero lifetime value. If the entry is a home entry get the 
157          * current lifetime. 
158          */
159
160         if (bulentry->lifetime != 0) {
161                 bulentry->lifetime = mipv6_mn_get_bulifetime(
162                         &bulentry->home_addr, &bulentry->coa, bulentry->flags);
163
164                 bulentry->expire = now + bulentry->lifetime * HZ;
165         } else {
166                 bulentry->expire = now + HOME_RESEND_EXPIRE * HZ; 
167         }
168         if (bulentry->rr) {
169                 /* Redo RR, if cookies have expired */
170                 if (time_after(jiffies, (unsigned long)(bulentry->rr->home_time + MAX_NONCE_LIFE * HZ)))
171                         bulentry->rr->rr_state |= RR_WAITH;
172                 if (time_after(jiffies, (unsigned long)(bulentry->rr->careof_time + MAX_NONCE_LIFE * HZ)))
173                         bulentry->rr->rr_state |= RR_WAITC;
174
175                 if (bulentry->rr->rr_state & RR_WAITH) {
176                                 /* Resend HoTI directly */
177                         mipv6_send_addr_test_init(&bulentry->home_addr, 
178                                                   &bulentry->cn_addr, MIPV6_MH_HOTI,
179                                                   bulentry->rr->hot_cookie);
180                 }
181                 if (bulentry->rr->rr_state & RR_WAITC) {
182                                 /* Resend CoTI directly */
183                                 mipv6_send_addr_test_init(&bulentry->coa, 
184                                                           &bulentry->cn_addr, MIPV6_MH_COTI,
185                                                           bulentry->rr->cot_cookie);
186                         }
187                 goto out;
188         }
189         
190         bulentry->seq++;
191
192         if (send_bu_msg(bulentry) < 0)
193                 DEBUG(DBG_ERROR, "Resending of BU failed");
194
195 out:
196         /* Schedule next retransmission */
197         if (bulentry->delay < bulentry->maxdelay) {
198                 bulentry->delay = 2 * bulentry->delay;
199                 if (bulentry->delay > bulentry->maxdelay) {
200                         /* can happen if maxdelay is not power(mindelay, 2) */
201                         bulentry->delay = bulentry->maxdelay;
202                 }
203         } else if (bulentry->flags & MIPV6_BU_F_HOME) {
204                 /* Home registration - continue sending BU at maxdelay rate */
205                 DEBUG(DBG_INFO, "Sending BU to HA after max ack wait time "
206                       "reached(0x%x)", (int) bulentry);
207                 bulentry->delay = bulentry->maxdelay;
208         } else if (!(bulentry->flags & MIPV6_BU_F_HOME)) {
209                 /* Failed to get BA from a CN */
210                 bulentry->callback_time = now;
211                 return -1;
212         }
213         
214         bulentry->callback_time = now + bulentry->delay * HZ;
215         return 0;
216 }
217
218
219
220 /* Callback for sending a registration refresh BU
221  */
222 static int bul_refresh(struct mipv6_bul_entry *bulentry)
223 {
224         unsigned long now = jiffies;
225         
226         /* Refresh interval passed, send new BU */
227         DEBUG(DBG_INFO, "bul entry 0x%x refresh interval passed, sending new BU", (int) bulentry);
228         if (bulentry->lifetime == 0)
229                 return 0;
230
231         /* Set new maximum lifetime and expiration time */
232         bulentry->lifetime = mipv6_mn_get_bulifetime(&bulentry->home_addr, 
233                                                      &bulentry->coa, 
234                                                      bulentry->flags);
235         bulentry->expire = now + bulentry->lifetime * HZ;
236         bulentry->seq++;
237         /* Send update */
238         if (send_bu_msg(bulentry) < 0)
239                 DEBUG(DBG_ERROR, "Resending of BU failed");
240         
241         if (bulentry->expire <= now) {
242                 /* Sanity check */
243                 DEBUG(DBG_ERROR, "bul entry expire time in history - setting expire to %u secs", ERROR_DEF_LIFETIME);
244                 bulentry->lifetime = ERROR_DEF_LIFETIME;
245                 bulentry->expire = now + ERROR_DEF_LIFETIME*HZ;
246         }
247
248         /* Set up retransmission */
249         bulentry->state = RESEND_EXP;
250         bulentry->callback = bul_resend_exp;
251         bulentry->callback_time = now + INITIAL_BINDACK_TIMEOUT*HZ;
252         bulentry->delay = INITIAL_BINDACK_TIMEOUT;
253         bulentry->maxdelay = MAX_BINDACK_TIMEOUT;
254
255         return 0;
256 }
257
258 static int mipv6_send_RR_bu(struct mipv6_bul_entry *bulentry)
259 {
260         int ret;
261         int ops_len = 0;
262         u16 nonces[2];
263
264         DEBUG(DBG_INFO, "Sending BU to CN  %x:%x:%x:%x:%x:%x:%x:%x "
265               "for home address %x:%x:%x:%x:%x:%x:%x:%x", 
266               NIPV6ADDR(&bulentry->cn_addr), NIPV6ADDR(&bulentry->home_addr));
267         nonces[0] = bulentry->rr->home_nonce_index;
268         nonces[1] = bulentry->rr->careof_nonce_index;
269         ops_len = sizeof(struct mipv6_mo_bauth_data) + MIPV6_RR_MAC_LENGTH + 
270                         sizeof(struct mipv6_mo_nonce_indices);
271         if (bulentry->ops) {
272                 DEBUG(DBG_WARNING, "Bul entry had existing mobility options, freeing them");
273                 kfree(bulentry->ops);
274         }
275         bulentry->ops = alloc_mh_opts(ops_len);
276
277         if (!bulentry->ops)
278                 return -ENOMEM;
279         if (append_mh_opt(bulentry->ops, MIPV6_OPT_NONCE_INDICES, 
280                           sizeof(struct mipv6_mo_nonce_indices) - 2, nonces) < 0)
281                 return -ENOMEM;
282
283         if (append_mh_opt(bulentry->ops, MIPV6_OPT_AUTH_DATA,
284                           MIPV6_RR_MAC_LENGTH, NULL) < 0)
285                 return -ENOMEM;
286         /* RR procedure is over, send a BU */
287         if (!(bulentry->flags & MIPV6_BU_F_ACK)) {
288                 DEBUG(DBG_INFO, "Setting bul callback to bul_expires");
289                 bulentry->state = ACK_OK;
290                 bulentry->callback = bul_expired;
291                 bulentry->callback_time = jiffies + HZ * bulentry->lifetime;
292                 bulentry->expire = jiffies + HZ *  bulentry->lifetime;
293         }
294         else {
295                 bulentry->callback_time = jiffies + HZ;
296                 bulentry->expire = jiffies + HZ *  bulentry->lifetime;
297         }
298
299         ret  = send_bu_msg(bulentry);
300         mipv6_bul_reschedule(bulentry);
301         return ret;
302 }
303
304 static int mipv6_rr_state(struct mipv6_bul_entry *bul, struct in6_addr *saddr,
305                           struct in6_addr *coa, __u8 flags)
306 {
307         if (!rr_configured)
308                 return NO_RR;
309         if (flags & MIPV6_BU_F_HOME) {
310                 /* We don't need RR, this is a Home Registration */
311                 return NO_RR;
312         }
313         if (!bul || !bul->rr) {
314                 /* First time BU to CN, need RR */
315                 return DO_RR;
316         }
317
318         switch (bul->rr->rr_state) {
319         case RR_INIT:
320                 /* Need RR if first BU to CN */
321                 return DO_RR;
322         case RR_DONE:
323                 /* If MN moves to a new coa, do RR for it */
324                 if (!ipv6_addr_cmp(&bul->coa, coa))  
325                         return NO_RR; 
326                 else
327                         return DO_RR;
328         default:
329                 /*
330                  * We are in the middle of RR, the HoTI and CoTI have been
331                  * sent. But we haven't got HoT and CoT from the CN, so
332                  * don't do anything more at this time.
333                  */
334                 return INPROGRESS_RR;
335         }
336 }
337
338 /**
339  * mipv6_RR_start - Start Return Routability procedure
340  * @home_addr: home address
341  * @cn_addr: correspondent address
342  * @coa: care-of address
343  * @entry: binding update list entry (if any)
344  * @initdelay: initial ack timeout
345  * @maxackdelay: maximum ack timeout
346  * @flags: flags
347  * @lifetime: lifetime of binding
348  * @ops: mobility options
349  *
350  * Caller must hold @bul_lock (write).
351  **/
352 static int mipv6_RR_start(struct in6_addr *home_addr, struct in6_addr *cn_addr,
353                           struct in6_addr *coa, struct mipv6_bul_entry *entry,
354                           __u32 initdelay, __u32 maxackdelay, __u8 flags, 
355                           __u32 lifetime, struct mipv6_mh_opt *ops)
356 {
357         int ret = -1;
358         struct mipv6_bul_entry *bulentry = entry;
359         struct mipv6_rr_info *rr = NULL;
360         int seq = 0;
361         DEBUG_FUNC();
362         
363         /* Do RR procedure only for care-of address after handoff, 
364            if home cookie is still valid */
365         if (bulentry && bulentry->rr) {
366                 if (time_before(jiffies, (unsigned long)(bulentry->rr->home_time + MAX_NONCE_LIFE * HZ)) &&
367                     lifetime && !(ipv6_addr_cmp(home_addr, coa) == 0)) { 
368                         mipv6_rr_mn_cookie_create(bulentry->rr->cot_cookie); 
369                         DEBUG(DBG_INFO, "Bul entry and rr info exist, only doing RR for CoA");
370                         ipv6_addr_copy(&bulentry->coa, coa);
371                         bulentry->rr->rr_state |= RR_WAITC;
372                 } else if (!lifetime) { /* Send only HoTi when returning home */
373                         mipv6_rr_mn_cookie_create(bulentry->rr->hot_cookie); 
374                         DEBUG(DBG_INFO, "Bul entry and rr info exist, only doing RR for HoA");
375                         ipv6_addr_copy(&bulentry->coa, coa); /* Home address as CoA */
376                         bulentry->rr->rr_state |= RR_WAITH;
377                 }
378         } else {
379                 DEBUG(DBG_INFO, "Doing RR for both HoA and CoA");
380                 rr = kmalloc(sizeof(*rr), GFP_ATOMIC);
381                 memset(rr, 0, sizeof(*rr));
382                 mipv6_rr_mn_cookie_create(rr->cot_cookie);
383                 mipv6_rr_mn_cookie_create(rr->hot_cookie);
384                 rr->rr_state = RR_WAITHC;
385         } 
386
387         if (bulentry) 
388                 seq = bulentry->seq + 1;
389         else
390                 seq = 0;
391         /* Save the info in the BUL to retransmit the BU after RR is done */
392         /* Caller must hold bul_lock (write) since we don't */
393        
394         if ((bulentry = mipv6_bul_add(cn_addr, home_addr, coa, 
395                                       min_t(__u32, lifetime, MAX_RR_BINDING_LIFE),
396                                       seq, flags, bul_resend_exp, initdelay, 
397                                       RESEND_EXP, initdelay, 
398                                       maxackdelay, ops, 
399                                       rr)) == NULL) {
400                 DEBUG(DBG_INFO, "couldn't update BUL for HoTi");
401                 goto out;
402         }
403         rr = bulentry->rr; 
404         mipv6_send_addr_test_init(home_addr, cn_addr, MIPV6_MH_HOTI, 
405                                   rr->hot_cookie);
406         if (ipv6_addr_cmp(home_addr, coa) && lifetime) 
407                 mipv6_send_addr_test_init(coa, cn_addr, MIPV6_MH_COTI, rr->cot_cookie);
408         else {
409                 bulentry->rr->rr_state &= ~RR_WAITC;
410         }
411         ret = 0;
412 out:
413         return ret;
414 }
415
416 /*
417  * Status codes for mipv6_ba_rcvd()
418  */
419 #define STATUS_UPDATE 0
420 #define STATUS_REMOVE 1
421
422 /**
423  * mipv6_ba_rcvd - Update BUL for this Binding Acknowledgement
424  * @ifindex: interface BA came from
425  * @cnaddr: sender IPv6 address
426  * @home_addr: home address
427  * @sequence: sequence number
428  * @lifetime: lifetime granted by Home Agent in seconds
429  * @refresh: recommended resend interval
430  * @status: %STATUS_UPDATE (ack) or %STATUS_REMOVE (nack)
431  *
432  * This function must be called to notify the module of the receipt of
433  * a binding acknowledgement so that it can cease retransmitting the
434  * option. The caller must have validated the acknowledgement before calling
435  * this function. 'status' can be either STATUS_UPDATE in which case the
436  * binding acknowledgement is assumed to be valid and the corresponding
437  * binding update list entry is updated, or STATUS_REMOVE in which case
438  * the corresponding binding update list entry is removed (this can be
439  * used upon receiving a negative acknowledgement).
440  * Returns 0 if a matching binding update has been sent or non-zero if
441  * not.
442  */
443 static int mipv6_ba_rcvd(int ifindex, struct in6_addr *cnaddr, 
444                          struct in6_addr *home_addr, 
445                          u16 sequence, u32 lifetime, 
446                          u32 refresh, int status)
447 {
448         struct mipv6_bul_entry *bulentry;
449         unsigned long now = jiffies;
450         struct in6_addr coa;
451
452         DEBUG(DBG_INFO, "BA received with sequence number 0x%x, status: %d",
453               (int) sequence, status);
454
455         /* Find corresponding entry in binding update list. */
456         write_lock(&bul_lock);
457         if ((bulentry = mipv6_bul_get(cnaddr, home_addr)) == NULL) {
458                 DEBUG(DBG_INFO, "- discarded, no entry in bul matches BA source address");
459                 write_unlock(&bul_lock);
460                 return -1;
461         }
462         
463         ipv6_addr_copy(&coa, &bulentry->coa); 
464         if (status != 0) {
465                 DEBUG(DBG_WARNING, "- NACK - BA status:  %d, deleting bul entry", status);
466                 if (bulentry->flags & MIPV6_BU_F_HOME) {
467                         DEBUG(DBG_ERROR, "Home registration failed: BA status:  %d, deleting bul entry", status);
468                         mipv6_mn_set_home_reg(home_addr, 0);
469                 }
470                 write_unlock(&bul_lock);
471                 return mipv6_bul_delete(cnaddr, home_addr);
472         }
473
474         /* Check that sequence numbers match */
475         if (sequence != bulentry->seq) {
476                 /* retransmission handles bad seq number if needed */
477                 DEBUG(DBG_INFO, "BA discarded, seq number mismatch");
478                 write_unlock(&bul_lock);
479                 return -1;
480         }
481         bulentry->state = ACK_OK;
482
483         if (bulentry->flags & MIPV6_BU_F_HOME && lifetime > 0) {
484                 /* For home registrations: schedule a refresh binding update.
485                  * Use the refresh interval given by home agent or 80%
486                  * of lifetime, whichever is less.
487                  *
488                  * Adjust binding lifetime if 'granted' lifetime
489                  * (lifetime value in received binding acknowledgement)
490                  * is shorter than 'requested' lifetime (lifetime
491                  * value sent in corresponding binding update).
492                  * max((L_remain - (L_update - L_ack)), 0)
493                  */
494                 if (lifetime * HZ < (bulentry->expire - bulentry->lastsend)) {
495                         bulentry->expire = 
496                                 max_t(__u32, bulentry->expire - 
497                                       ((bulentry->expire - bulentry->lastsend) - 
498                                        lifetime * HZ), jiffies + 
499                                       ERROR_DEF_LIFETIME * HZ);
500                 }
501                 if (refresh > lifetime || refresh == 0)
502                         refresh = 4 * lifetime / 5;
503                         DEBUG(DBG_INFO, "setting callback for expiration of"
504                               " a Home Registration: lifetime:%d, refresh:%d",
505                               lifetime, refresh);
506                 bulentry->callback = bul_refresh;
507                 bulentry->callback_time = now + refresh * HZ;
508                 bulentry->expire = now + lifetime * HZ;
509                 bulentry->lifetime = lifetime;
510                 if (bulentry->expire <= jiffies) {
511                         /* Sanity check */
512                         DEBUG(DBG_ERROR, "bul entry expire time in history - setting expire to %u secs",
513                               ERROR_DEF_LIFETIME);
514                         bulentry->expire = jiffies + ERROR_DEF_LIFETIME * HZ;
515                 }
516                 mipv6_mn_set_home_reg(home_addr, 1);
517                 mipv6_bul_iterate(mn_cn_handoff, &coa);
518         } else if ((bulentry->flags & MIPV6_BU_F_HOME) && bulentry->lifetime == 0) {
519                 write_unlock(&bul_lock);
520                 DEBUG(DBG_INFO, "Got BA for deregistration BU");
521                 mipv6_mn_set_home_reg(home_addr, 0);
522                 mipv6_bul_delete(cnaddr, home_addr);
523                 mipv6_mn_send_home_na(home_addr);
524
525                 write_lock_bh(&bul_lock);
526                 mipv6_bul_iterate(mn_cn_handoff, &coa);
527                 write_unlock_bh(&bul_lock);
528                 return 0;
529         }
530
531         mipv6_bul_reschedule(bulentry);
532         write_unlock(&bul_lock);
533
534         return 0;
535 }
536
537 static int mipv6_handle_mh_HC_test(struct in6_addr *saddr,
538                                    struct in6_addr *coa,
539                                    struct in6_addr *cn,
540                                    struct in6_addr *unused,
541                                    struct mipv6_mh *mh)
542 {
543         int ret = 0;
544         int msg_len = (mh->length << 3) + 2;
545         struct mipv6_mh_addr_test *tm = (struct mipv6_mh_addr_test *)mh->data;
546         struct mipv6_bul_entry *bulentry;
547         
548         DEBUG_FUNC();
549
550         if (msg_len < sizeof(*tm)) {
551                 DEBUG(DBG_INFO, "Mobility Header length less than H/C Test");
552                 return -1;
553         }
554
555 #if 0 /* TODO: Use fcoa here */
556         if (hao) {
557                 DEBUG(DBG_INFO, "H/C Test has HAO, dropped.");
558                 return -1;
559         }
560 #endif
561
562         write_lock(&bul_lock);
563
564         /* We need to get the home address, since CoT only has the CoA*/
565         if (mh->type == MIPV6_MH_COT) {
566                 if ((bulentry = mipv6_bul_get_by_ccookie(cn, tm->init_cookie)) == NULL) {
567                         DEBUG(DBG_ERROR, "has no BUL or RR state for "
568                               "source:%x:%x:%x:%x:%x:%x:%x:%x",
569                               NIPV6ADDR(cn));
570                         write_unlock(&bul_lock);
571                         return -1;
572                 }
573         } else { /* HoT has the home address */
574                 if (((bulentry = mipv6_bul_get(cn, saddr)) == NULL) || !bulentry->rr) {
575                         DEBUG(DBG_ERROR, "has no BUL or RR state for "
576                               "source:%x:%x:%x:%x:%x:%x:%x:%x "
577                               "dest:%x:%x:%x:%x:%x:%x:%x:%x",
578                               NIPV6ADDR(cn), NIPV6ADDR(saddr));
579                         write_unlock(&bul_lock);
580                         return -1;
581                 }
582         }
583
584         switch (mh->type) {
585         case MIPV6_MH_HOT:
586                 if ((bulentry->rr->rr_state & RR_WAITH) == 0) {
587                         DEBUG(DBG_ERROR, "Not waiting for a Home Test message");
588                         goto out;
589                 }
590 #if 0
591                 /* Check for non-tunneled packet. TODO: How can one do this
592                  * now since skb is not passed ? */
593                 if (!(skb->security & RCV_TUNNEL)) {
594                         DEBUG(DBG_ERROR, "Received a untunneled packet");
595                         goto out;
596                 }
597 #endif
598                 /*
599                  * Make sure no home cookies have been received yet.
600                  * TODO: Check not being put in at this time since subsequent
601                  * BU's after this time will have home cookie stored.
602                  */
603         
604                 /* Check if the cookie received is the right one */
605                 if (!mipv6_equal_cookies(tm->init_cookie,
606                                          bulentry->rr->hot_cookie)) {
607                         /* Invalid cookie, might be an old cookie */
608                         DEBUG(DBG_WARNING, "Received HoT cookie does not match stored cookie");
609                         goto out;
610                 }
611                 DEBUG(DBG_INFO, "Got Care-of Test message");
612                 bulentry->rr->rr_state &= ~RR_WAITH;
613                 memcpy(bulentry->rr->home_cookie, tm->kgen_token, MIPV6_COOKIE_LEN);
614                 bulentry->rr->home_nonce_index = tm->nonce_index;
615                 bulentry->rr->home_time = jiffies;
616                 ret = 1;
617                 break;
618
619         case MIPV6_MH_COT:
620                 if ((bulentry->rr->rr_state & RR_WAITC) == 0) {
621                         DEBUG(DBG_ERROR, "Not waiting for a Home Test message");
622                         goto out;
623                 }
624                 /*
625                  * Make sure no home cookies have been received yet.
626                  * TODO: Check not being put in at this time since subsequent
627                  * BU's at this time will have careof cookie stored.
628                  */
629         
630                 /* Check if the cookie received is the right one */
631                 if (!mipv6_equal_cookies(tm->init_cookie,
632                                          bulentry->rr->cot_cookie)) {
633                         DEBUG(DBG_INFO, "Received CoT cookie does not match stored cookie");
634                         goto out;
635                 }
636                 bulentry->rr->rr_state &= ~RR_WAITC;
637                 memcpy(bulentry->rr->careof_cookie, tm->kgen_token, MIPV6_COOKIE_LEN);
638                 bulentry->rr->careof_nonce_index = tm->nonce_index;
639                 bulentry->rr->careof_time = jiffies;
640                 ret = 1;
641                 break;
642         default:
643                 /* Impossible to get here */
644                 break;
645         }
646 out:
647         if (bulentry->rr->rr_state == RR_DONE) {
648                 if (bulentry->rr->kbu) /* First free any old keys */
649                         kfree(bulentry->rr->kbu);
650                 /* Store the session key to be used in BU's */
651                 if (ipv6_addr_cmp(&bulentry->coa, &bulentry->home_addr) && bulentry->lifetime)
652                         bulentry->rr->kbu = mipv6_rr_key_calc(bulentry->rr->home_cookie,
653                                                               bulentry->rr->careof_cookie);
654                 else 
655                         bulentry->rr->kbu = mipv6_rr_key_calc(bulentry->rr->home_cookie,
656                                                               NULL);
657                 /* RR procedure is over, send a BU */
658                 mipv6_send_RR_bu(bulentry);
659         }
660         write_unlock(&bul_lock);
661         return ret;
662 }
663
664 /**
665  * mipv6_handle_mh_brr - Binding Refresh Request handler
666  * @home: home address
667  * @coa: care-of address
668  * @cn: source of this packet
669  * @mh: pointer to the beginning of the Mobility Header
670  *
671  * Handles Binding Refresh Request.  Packet and offset to option are
672  * passed.  Returns 0 on success, otherwise negative.
673  **/
674 static int mipv6_handle_mh_brr(struct in6_addr *home,
675                                struct in6_addr *coa,
676                                struct in6_addr *cn,
677                                struct in6_addr *unused,
678                                struct mipv6_mh *mh)
679 {
680         struct mipv6_mh_brr *brr = (struct mipv6_mh_brr *)mh->data;
681         struct mipv6_bul_entry *binding;
682         int msg_len = (mh->length << 3) + 2;
683
684         if (msg_len < sizeof(*brr)) {
685                 DEBUG(DBG_WARNING, "Mobility Header length less than BRR");
686                 MIPV6_INC_STATS(n_brr_drop.invalid);
687                 return -1;
688         }
689
690         /* check we know src, else drop */
691         write_lock(&bul_lock);
692         if ((binding = mipv6_bul_get(cn, home)) == NULL) {
693                 MIPV6_INC_STATS(n_brr_drop.misc);
694                 write_unlock(&bul_lock);
695                 return MH_UNKNOWN_CN;
696         }
697
698         MIPV6_INC_STATS(n_brr_rcvd);
699
700         if (msg_len > sizeof(*brr)) {
701                 struct mobopt opts;
702                 memset(&opts, 0, sizeof(opts));
703                 if (parse_mo_tlv(brr + 1, msg_len - sizeof(*brr), &opts) < 0) {
704                         write_unlock(&bul_lock);
705                         return -1;
706                 }
707                 /*
708                  * MIPV6_OPT_AUTH_DATA
709                  */
710         }
711
712         /* must hold bul_lock (write) */
713         mipv6_RR_start(home, cn, coa, binding, binding->delay, 
714                        binding->maxdelay, binding->flags,
715                        binding->lifetime, binding->ops);
716
717         write_unlock(&bul_lock);
718         /* MAY also decide to delete binding and send zero lifetime BU
719            with alt-coa set to home address */
720
721         return 0;
722 }
723
724 /**
725  * mipv6_handle_mh_ba - Binding Acknowledgement handler
726  * @src: source of this packet
727  * @coa: care-of address
728  * @home: home address
729  * @mh: pointer to the beginning of the Mobility Header
730  *
731  **/
732 static int mipv6_handle_mh_ba(struct in6_addr *home,
733                               struct in6_addr *coa,
734                               struct in6_addr *src,
735                               struct in6_addr *unused,
736                               struct mipv6_mh *mh)
737 {
738         struct mipv6_mh_ba *ba = (struct mipv6_mh_ba *)mh->data;
739         struct mipv6_bul_entry *binding = NULL;
740         struct mobopt opts;
741         int msg_len = (mh->length << 3)  + 2;
742         int auth = 1, req_auth = 1, refresh = -1, ifindex = 0;
743         u32 lifetime, sequence;
744
745         if (msg_len < sizeof(*ba)) {
746                 DEBUG(DBG_WARNING, "Mobility Header length less than BA");
747                 MIPV6_INC_STATS(n_ba_drop.invalid);
748                 return -1;
749         }
750
751         lifetime = ntohs(ba->lifetime) << 2;
752         sequence = ntohs(ba->sequence);
753
754         if (msg_len > sizeof(*ba)) {
755                 memset(&opts, 0, sizeof(opts));
756                 if (parse_mo_tlv(ba + 1, msg_len - sizeof(*ba), &opts) < 0)
757                         return -1;
758                 /*
759                  * MIPV6_OPT_AUTH_DATA, MIPV6_OPT_BR_ADVICE
760                  */
761                 if (opts.br_advice)
762                         refresh = ntohs(opts.br_advice->refresh_interval);
763         }
764
765         if (ba->status >= EXPIRED_HOME_NONCE_INDEX && 
766             ba->status <= EXPIRED_NONCES) 
767                 req_auth = 0;
768         
769         write_lock(&bul_lock);
770         binding = mipv6_bul_get(src, home);
771         if (!binding) {
772                 DEBUG(DBG_INFO, "No binding, BA dropped.");
773                 write_unlock(&bul_lock);
774                 return -1;
775         }
776
777         if (opts.auth_data && binding->rr && (mipv6_auth_check(
778                 src, coa, (__u8 *)mh, msg_len, opts.auth_data, binding->rr->kbu) == 0))
779                 auth = 1;
780
781         if (req_auth && binding->rr && !auth) {
782                 DEBUG(DBG_INFO, "BA Authentication failed.");
783                 MIPV6_INC_STATS(n_ba_drop.auth);
784                 write_unlock(&bul_lock);
785                 return MH_AUTH_FAILED;
786         }
787
788         if (ba->status == SEQUENCE_NUMBER_OUT_OF_WINDOW) {
789                 DEBUG(DBG_INFO,
790                       "Sequence number out of window, setting seq to %d",
791                       sequence);
792                 binding->seq = sequence + 1;
793                 MIPV6_INC_STATS(n_ban_rcvd);
794                 send_bu_msg(binding);
795                 
796                 write_unlock(&bul_lock);
797                 return 1;
798         }
799
800         if (binding->seq != sequence) {
801                 DEBUG(DBG_INFO, "BU/BA Sequence Number mismatch %d != %d",
802                       binding->seq, sequence);
803                 MIPV6_INC_STATS(n_ba_drop.invalid);
804                 write_unlock(&bul_lock);
805                 return MH_SEQUENCE_MISMATCH;
806         }
807         if (ba->status == EXPIRED_HOME_NONCE_INDEX || ba->status == EXPIRED_NONCES) {
808                 if (binding->rr) {
809                         /* Need to resend home test init to CN */
810                         binding->rr->rr_state |= RR_WAITH;
811                         mipv6_send_addr_test_init(&binding->home_addr, 
812                                                   &binding->cn_addr, 
813                                                   MIPV6_MH_HOTI,
814                                                   binding->rr->hot_cookie);
815                         MIPV6_INC_STATS(n_ban_rcvd);
816                 } else {
817                         DEBUG(DBG_WARNING, "Got BA with status EXPIRED_HOME_NONCE_INDEX"
818                               "for non-RR BU");
819                         MIPV6_INC_STATS(n_ba_drop.invalid);
820                 }
821                 write_unlock(&bul_lock);
822                 return 0;
823         } 
824         if (ba->status == EXPIRED_CAREOF_NONCE_INDEX || ba->status == EXPIRED_NONCES) {
825                 if (binding->rr) { 
826                         /* Need to resend care-of test init to CN */
827                         binding->rr->rr_state |= RR_WAITC;
828                         mipv6_send_addr_test_init(&binding->coa, 
829                                                   &binding->cn_addr, 
830                                                   MIPV6_MH_COTI,
831                                                   binding->rr->cot_cookie);
832                         MIPV6_INC_STATS(n_ban_rcvd);
833                 } else  {
834                         DEBUG(DBG_WARNING, "Got BA with status EXPIRED_HOME_CAREOF_INDEX"
835                               "for non-RR BU");
836                         MIPV6_INC_STATS(n_ba_drop.invalid);
837                 }
838                 write_unlock(&bul_lock);
839                 return 0;
840         }
841         write_unlock(&bul_lock);
842         
843         if (ba->status >= REASON_UNSPECIFIED) {
844                 DEBUG(DBG_INFO, "Binding Ack status : %d indicates error", ba->status);
845                 mipv6_ba_rcvd(ifindex, src, home, ntohs(ba->sequence), lifetime,
846                               refresh, ba->status);
847                 MIPV6_INC_STATS(n_ban_rcvd);
848                 return 0;
849         }
850
851         if (ba->status != 0) {
852                 /* Unknown BA status */
853                 MIPV6_INC_STATS(n_ba_drop.invalid);
854                 return 0;
855         }
856         
857         MIPV6_INC_STATS(n_ba_rcvd);
858         if (mipv6_ba_rcvd(ifindex, src, home, ntohs(ba->sequence), lifetime,
859                           refresh, ba->status)) {
860                 DEBUG(DBG_WARNING, "mipv6_ba_rcvd failed");
861         }
862         
863         return 0;
864 }
865
866 /**
867  * mipv6_handle_mh_be - Binding Error handler
868  * @cn: source of this packet
869  * @coa: care-of address
870  * @home: home address
871  * @mh: pointer to the beginning of the Mobility Header
872  *
873  **/
874 static int mipv6_handle_mh_be(struct in6_addr *home,
875                               struct in6_addr *coa,
876                               struct in6_addr *cn,
877                               struct in6_addr *unused,
878                               struct mipv6_mh *mh)
879 {
880         struct mipv6_mh_be *be = (struct mipv6_mh_be *)mh->data;
881         int msg_len = (mh->length << 3)  + 2;
882
883         if (msg_len < sizeof(*be)) {
884                 DEBUG(DBG_WARNING, "Mobility Header length less than BE");
885                 MIPV6_INC_STATS(n_be_drop.invalid);
886                 return -1;
887         }
888
889         /* check we know src, else drop */
890         if (!mipv6_bul_exists(cn, home)) {
891                 MIPV6_INC_STATS(n_be_drop.misc);
892                 return MH_UNKNOWN_CN;
893         }
894
895         if (msg_len > sizeof(*be)) {
896                 /* no valid Mobility Options this time, just ignore */
897         }
898
899         MIPV6_INC_STATS(n_be_rcvd);
900         switch (be->status) {
901         case 1: /* Home Address Option used without a binding */
902                 /* Get ULP information about CN-MN communication.  If
903                    nothing in progress, MUST delete.  Otherwise MAY
904                    ignore. */
905                 mipv6_bul_delete(cn, home);
906                 break;
907         case 2: /* Received unknown MH type */
908                 /* If not expecting ack, SHOULD ignore.  If MH
909                    extension in use, stop it.  If not, stop RO for
910                    this CN. */
911                 break;
912         }
913
914         return 0;
915 }
916
917 /*
918  * mipv6_bu_rate_limit() : Takes a bulentry, a COA and 'flags' to check
919  * whether BU being sent is for Home Registration or not.
920  *
921  * If the number of BU's sent is fewer than MAX_FAST_UPDATES, this BU
922  * is allowed to be sent at the MAX_UPDATE_RATE.
923  * If the number of BU's sent is greater than or equal to MAX_FAST_UPDATES,
924  * this BU is allowed to be sent at the SLOW_UPDATE_RATE.
925  *
926  * Assumption : This function is not re-entrant. and the caller holds the
927  * bulentry lock (by calling mipv6_bul_get()) to stop races with other
928  * CPU's executing this same function.
929  *
930  * Side-Effects. Either of the following could  on success :
931  *      1. Sets consecutive_sends to 1 if the entry is a Home agent
932  *         registration or the COA has changed.
933  *      2. Increments consecutive_sends if the number of BU's sent so
934  *         far is less than MAX_FAST_UPDATES, and this BU is being sent
935  *         atleast MAX_UPDATE_RATE after previous one.
936  * 
937  * Return Value : 0 on Success, -1 on Failure
938  */
939 static int mipv6_bu_rate_limit(struct mipv6_bul_entry *bulentry, 
940                                struct in6_addr *coa, __u8 flags)
941 {
942         if ((flags & MIPV6_BU_F_HOME) || ipv6_addr_cmp(&bulentry->coa, coa)) {
943                 /* Home Agent Registration or different COA - restart from 1 */
944                 bulentry->consecutive_sends = 1;
945                 return 0;
946         }
947
948         if (bulentry->consecutive_sends < MAX_FAST_UPDATES) {
949                 /* First MAX_FAST_UPDATES can be sent at MAX_UPDATE_RATE */
950                 if (jiffies - bulentry->lastsend < MAX_UPDATE_RATE * HZ) {
951                         return -1;
952                 }
953                 bulentry->consecutive_sends ++;
954         } else {
955                 /* Remaining updates SHOULD be sent at SLOW_UPDATE_RATE */
956                 if (jiffies - bulentry->lastsend < SLOW_UPDATE_RATE * HZ) {
957                         return -1;
958                 }
959                 /* Don't inc 'consecutive_sends' to avoid overflow to zero */
960         }
961         /* OK to send a BU */
962         return 0;
963 }
964
965 /**
966  * mipv6_send_bu - send a Binding Update 
967  * @saddr: source address for BU
968  * @daddr: destination address for BU
969  * @coa: care-of address for MN
970  * @initdelay: initial BA wait timeout
971  * @maxackdelay: maximum BA wait timeout
972  * @exp: exponention back off
973  * @flags: flags for BU
974  * @lifetime: granted lifetime for binding
975  * @ops: mobility options
976  *
977  * Send a binding update.  'flags' may contain any of %MIPV6_BU_F_ACK,
978  * %MIPV6_BU_F_HOME, %MIPV6_BU_F_ROUTER bitwise ORed.  If
979  * %MIPV6_BU_F_ACK is included retransmission will be attempted until
980  * the update has been acknowledged.  Retransmission is done if no
981  * acknowledgement is received within @initdelay seconds.  @exp
982  * specifies whether to use exponential backoff (@exp != 0) or linear
983  * backoff (@exp == 0).  For exponential backoff the time to wait for
984  * an acknowledgement is doubled on each retransmission until a delay
985  * of @maxackdelay, after which retransmission is no longer attempted.
986  * For linear backoff the delay is kept constant and @maxackdelay
987  * specifies the maximum number of retransmissions instead.  If
988  * sub-options are present ops must contain all sub-options to be
989  * added.  On a mobile node, use the mobile node's home address for
990  * @saddr.  Returns 0 on success, non-zero on failure.
991  *
992  * Caller may not hold @bul_lock.
993  **/
994 int mipv6_send_bu(struct in6_addr *saddr, struct in6_addr *daddr,
995                   struct in6_addr *coa, u32 initdelay, 
996                   u32 maxackdelay, u8 exp, u8 flags, u32 lifetime,
997                   struct mipv6_mh_opt *ops)
998 {
999         int ret;
1000         __u8 state;
1001          __u16 seq = 0;
1002         int (*callback)(struct mipv6_bul_entry *);
1003         __u32 callback_time;
1004         struct mipv6_bul_entry *bulentry;
1005         
1006         /* First a sanity check: don't send BU to local addresses */
1007         if(ipv6_chk_addr(daddr, NULL, 0)) {
1008                 DEBUG(DBG_ERROR, "BUG: Trying to send BU to local address");
1009                 return -1;
1010         }
1011         DEBUG(DBG_INFO, "Sending BU to CN  %x:%x:%x:%x:%x:%x:%x:%x "
1012               "for home address %x:%x:%x:%x:%x:%x:%x:%x", 
1013               NIPV6ADDR(daddr), NIPV6ADDR(saddr));
1014
1015         if ((bulentry = mipv6_bul_get(daddr, saddr)) != NULL) {
1016                 if (bulentry->state == ACK_ERROR) {
1017                         /*
1018                          * Don't send any more BU's to nodes which don't
1019                          * understanding one. 
1020                          */
1021                         DEBUG(DBG_INFO, "Not sending BU to node which doesn't"
1022                               " understand one");
1023                         return -1;
1024                 }
1025                 if (mipv6_bu_rate_limit(bulentry, coa, flags) < 0) {
1026                         DEBUG(DBG_DATADUMP, "Limiting BU sent.");
1027                         return 0;
1028                 }
1029         }
1030
1031         switch (mipv6_rr_state(bulentry, saddr, coa, flags)) {
1032         case INPROGRESS_RR:
1033                 /* We are already doing RR, don't do BU at this time, it is
1034                  * done automatically later */
1035                 DEBUG(DBG_INFO, "RR in progress not sending BU");
1036                 return 0;
1037
1038         case DO_RR:
1039                 /* Just do RR and return, BU is done automatically later */
1040                 DEBUG(DBG_INFO, "starting RR" );
1041                 mipv6_RR_start(saddr, daddr, coa, bulentry, initdelay,
1042                                maxackdelay, flags, lifetime, ops);
1043                 return 0;
1044                 
1045         case NO_RR:
1046                 DEBUG(DBG_DATADUMP, "No RR necessary" );
1047         default:
1048                 break;
1049         }
1050
1051         if (bulentry)
1052                 seq = bulentry->seq + 1;
1053         
1054         /* Add to binding update list */
1055         
1056         if (flags & MIPV6_BU_F_ACK) {
1057                 DEBUG(DBG_INFO, "Setting bul callback to bul_resend_exp");
1058                 /* Send using exponential backoff */
1059                 state = RESEND_EXP;
1060                 callback = bul_resend_exp;
1061                 callback_time = initdelay;
1062         } else {
1063                 DEBUG(DBG_INFO, "Setting bul callback to bul_expired");
1064                 /* No acknowledgement/resending required */
1065                 state = ACK_OK; /* pretend we got an ack */
1066                 callback = bul_expired;
1067                 callback_time = lifetime;
1068         }
1069
1070         /* BU only for the home address */
1071         /* We must hold bul_lock (write) while calling add */
1072         if ((bulentry = mipv6_bul_add(daddr, saddr, coa, lifetime, seq,
1073                                       flags, callback, callback_time, 
1074                                       state, initdelay, maxackdelay, ops, 
1075                                       NULL)) == NULL) {
1076                 DEBUG(DBG_INFO, "couldn't update BUL");
1077                 return 0;
1078         }
1079         ret = send_bu_msg(bulentry);
1080
1081         return ret;
1082 }
1083
1084 int __init mipv6_mh_mn_init(void)
1085 {
1086         mipv6_mh_register(MIPV6_MH_HOT, mipv6_handle_mh_HC_test);
1087         mipv6_mh_register(MIPV6_MH_COT, mipv6_handle_mh_HC_test);
1088         mipv6_mh_register(MIPV6_MH_BA, mipv6_handle_mh_ba);
1089         mipv6_mh_register(MIPV6_MH_BRR, mipv6_handle_mh_brr);
1090         mipv6_mh_register(MIPV6_MH_BE, mipv6_handle_mh_be);
1091
1092         return 0;
1093 }
1094
1095 void __exit mipv6_mh_mn_exit(void)
1096 {
1097         mipv6_mh_unregister(MIPV6_MH_HOT);
1098         mipv6_mh_unregister(MIPV6_MH_COT);
1099         mipv6_mh_unregister(MIPV6_MH_BA);
1100         mipv6_mh_unregister(MIPV6_MH_BRR);
1101         mipv6_mh_unregister(MIPV6_MH_BE);
1102 }