2 * Mobile IPv6 Mobility Header Functions for Mobile Node
5 * Antti Tuominen <ajtuomin@tml.hut.fi>
6 * Niklas Kämpe <nhkampe@cc.hut.fi>
7 * Henrik Petander <henrik.petander@hut.fi>
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.
18 #include <linux/types.h>
19 #include <linux/sched.h>
20 #include <linux/init.h>
22 #include <net/addrconf.h>
23 #include <net/mipv6.h>
28 #include "rr_crypto.h"
33 int rr_configured = 1;
35 /* Return value of mipv6_rr_state() */
39 #define INPROGRESS_RR 3
42 * send_bu_msg - sends a Binding Update
43 * @bulentry : BUL entry with the information for building a BU
45 * Function builds a BU msg based on the contents of a bul entry.
46 * Does not change the bul entry.
48 static int send_bu_msg(struct mipv6_bul_entry *binding)
50 int auth = 0; /* Use auth */
52 struct mipv6_auth_parm parm;
53 struct mipv6_mh_bu bu;
58 DEBUG(DBG_ERROR, "called with a null bul entry");
62 memset(&parm, 0, sizeof(parm));
63 if (mipv6_prefix_compare(&binding->coa, &binding->home_addr, 64))
64 parm.coa = &binding->home_addr;
66 parm.coa = &binding->coa;
67 parm.cn_addr = &binding->cn_addr;
69 if (binding->rr && binding->rr->kbu) {
70 DEBUG(DBG_INFO, "Binding with key");
72 parm.k_bu = binding->rr->kbu;
74 memset(&bu, 0, sizeof(bu));
75 bu.flags = binding->flags;
76 bu.sequence = htons(binding->seq);
77 bu.lifetime = htons(binding->lifetime >> 2);
80 ret = send_mh(&binding->cn_addr, &binding->home_addr,
81 MIPV6_MH_BU, sizeof(bu), (u8 *)&bu,
82 &binding->home_addr, NULL,
86 MIPV6_INC_STATS(n_bu_sent);
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
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.
102 static int mipv6_send_addr_test_init(struct in6_addr *saddr,
103 struct in6_addr *daddr,
107 struct mipv6_mh_addr_ti ti;
108 struct mipv6_mh_opt *ops = NULL;
111 /* Set reserved and copy the cookie from address test init msg */
113 memcpy(ti.init_cookie, init_cookie, MIPV6_RR_COOKIE_LENGTH);
115 ret = send_mh(daddr, saddr, msg_type, sizeof(ti), (u8 *)&ti,
116 NULL, NULL, ops, NULL);
118 if (msg_type == MIPV6_MH_HOTI) {
119 MIPV6_INC_STATS(n_hoti_sent);
121 MIPV6_INC_STATS(n_coti_sent);
130 * Callback handlers for binding update list
134 /* Return value 0 means keep entry, non-zero means discard entry. */
136 /* Callback for BUs not requiring acknowledgement
138 static int bul_expired(struct mipv6_bul_entry *bulentry)
140 /* Lifetime expired, delete entry. */
141 DEBUG(DBG_INFO, "bul entry 0x%x lifetime expired, deleting entry", (int) bulentry);
145 /* Callback for BUs requiring acknowledgement with exponential resending
147 static int bul_resend_exp(struct mipv6_bul_entry *bulentry)
149 unsigned long now = jiffies;
151 DEBUG(DBG_INFO, "(0x%x) resending bu", (int) bulentry);
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
160 if (bulentry->lifetime != 0) {
161 bulentry->lifetime = mipv6_mn_get_bulifetime(
162 &bulentry->home_addr, &bulentry->coa, bulentry->flags);
164 bulentry->expire = now + bulentry->lifetime * HZ;
166 bulentry->expire = now + HOME_RESEND_EXPIRE * HZ;
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;
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);
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);
192 if (send_bu_msg(bulentry) < 0)
193 DEBUG(DBG_ERROR, "Resending of BU failed");
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;
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;
214 bulentry->callback_time = now + bulentry->delay * HZ;
220 /* Callback for sending a registration refresh BU
222 static int bul_refresh(struct mipv6_bul_entry *bulentry)
224 unsigned long now = jiffies;
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)
231 /* Set new maximum lifetime and expiration time */
232 bulentry->lifetime = mipv6_mn_get_bulifetime(&bulentry->home_addr,
235 bulentry->expire = now + bulentry->lifetime * HZ;
238 if (send_bu_msg(bulentry) < 0)
239 DEBUG(DBG_ERROR, "Resending of BU failed");
241 if (bulentry->expire <= now) {
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;
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;
258 static int mipv6_send_RR_bu(struct mipv6_bul_entry *bulentry)
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);
272 DEBUG(DBG_WARNING, "Bul entry had existing mobility options, freeing them");
273 kfree(bulentry->ops);
275 bulentry->ops = alloc_mh_opts(ops_len);
279 if (append_mh_opt(bulentry->ops, MIPV6_OPT_NONCE_INDICES,
280 sizeof(struct mipv6_mo_nonce_indices) - 2, nonces) < 0)
283 if (append_mh_opt(bulentry->ops, MIPV6_OPT_AUTH_DATA,
284 MIPV6_RR_MAC_LENGTH, NULL) < 0)
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;
295 bulentry->callback_time = jiffies + HZ;
296 bulentry->expire = jiffies + HZ * bulentry->lifetime;
299 ret = send_bu_msg(bulentry);
300 mipv6_bul_reschedule(bulentry);
304 static int mipv6_rr_state(struct mipv6_bul_entry *bul, struct in6_addr *saddr,
305 struct in6_addr *coa, __u8 flags)
309 if (flags & MIPV6_BU_F_HOME) {
310 /* We don't need RR, this is a Home Registration */
313 if (!bul || !bul->rr) {
314 /* First time BU to CN, need RR */
318 switch (bul->rr->rr_state) {
320 /* Need RR if first BU to CN */
323 /* If MN moves to a new coa, do RR for it */
324 if (!ipv6_addr_cmp(&bul->coa, coa))
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.
334 return INPROGRESS_RR;
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
347 * @lifetime: lifetime of binding
348 * @ops: mobility options
350 * Caller must hold @bul_lock (write).
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)
358 struct mipv6_bul_entry *bulentry = entry;
359 struct mipv6_rr_info *rr = NULL;
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;
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;
388 seq = bulentry->seq + 1;
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 */
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,
400 DEBUG(DBG_INFO, "couldn't update BUL for HoTi");
404 mipv6_send_addr_test_init(home_addr, cn_addr, MIPV6_MH_HOTI,
406 if (ipv6_addr_cmp(home_addr, coa) && lifetime)
407 mipv6_send_addr_test_init(coa, cn_addr, MIPV6_MH_COTI, rr->cot_cookie);
409 bulentry->rr->rr_state &= ~RR_WAITC;
417 * Status codes for mipv6_ba_rcvd()
419 #define STATUS_UPDATE 0
420 #define STATUS_REMOVE 1
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)
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
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)
448 struct mipv6_bul_entry *bulentry;
449 unsigned long now = jiffies;
452 DEBUG(DBG_INFO, "BA received with sequence number 0x%x, status: %d",
453 (int) sequence, status);
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);
463 ipv6_addr_copy(&coa, &bulentry->coa);
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);
470 write_unlock(&bul_lock);
471 return mipv6_bul_delete(cnaddr, home_addr);
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);
481 bulentry->state = ACK_OK;
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.
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)
494 if (lifetime * HZ < (bulentry->expire - bulentry->lastsend)) {
496 max_t(__u32, bulentry->expire -
497 ((bulentry->expire - bulentry->lastsend) -
498 lifetime * HZ), jiffies +
499 ERROR_DEF_LIFETIME * HZ);
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",
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) {
512 DEBUG(DBG_ERROR, "bul entry expire time in history - setting expire to %u secs",
514 bulentry->expire = jiffies + ERROR_DEF_LIFETIME * HZ;
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);
525 write_lock_bh(&bul_lock);
526 mipv6_bul_iterate(mn_cn_handoff, &coa);
527 write_unlock_bh(&bul_lock);
531 mipv6_bul_reschedule(bulentry);
532 write_unlock(&bul_lock);
537 static int mipv6_handle_mh_HC_test(struct in6_addr *saddr,
538 struct in6_addr *coa,
540 struct in6_addr *unused,
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;
550 if (msg_len < sizeof(*tm)) {
551 DEBUG(DBG_INFO, "Mobility Header length less than H/C Test");
555 #if 0 /* TODO: Use fcoa here */
557 DEBUG(DBG_INFO, "H/C Test has HAO, dropped.");
562 write_lock(&bul_lock);
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",
570 write_unlock(&bul_lock);
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);
586 if ((bulentry->rr->rr_state & RR_WAITH) == 0) {
587 DEBUG(DBG_ERROR, "Not waiting for a Home Test message");
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");
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.
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");
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;
620 if ((bulentry->rr->rr_state & RR_WAITC) == 0) {
621 DEBUG(DBG_ERROR, "Not waiting for a Home Test message");
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.
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");
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;
643 /* Impossible to get here */
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);
655 bulentry->rr->kbu = mipv6_rr_key_calc(bulentry->rr->home_cookie,
657 /* RR procedure is over, send a BU */
658 mipv6_send_RR_bu(bulentry);
660 write_unlock(&bul_lock);
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
671 * Handles Binding Refresh Request. Packet and offset to option are
672 * passed. Returns 0 on success, otherwise negative.
674 static int mipv6_handle_mh_brr(struct in6_addr *home,
675 struct in6_addr *coa,
677 struct in6_addr *unused,
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;
684 if (msg_len < sizeof(*brr)) {
685 DEBUG(DBG_WARNING, "Mobility Header length less than BRR");
686 MIPV6_INC_STATS(n_brr_drop.invalid);
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;
698 MIPV6_INC_STATS(n_brr_rcvd);
700 if (msg_len > sizeof(*brr)) {
702 memset(&opts, 0, sizeof(opts));
703 if (parse_mo_tlv(brr + 1, msg_len - sizeof(*brr), &opts) < 0) {
704 write_unlock(&bul_lock);
708 * MIPV6_OPT_AUTH_DATA
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);
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 */
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
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,
738 struct mipv6_mh_ba *ba = (struct mipv6_mh_ba *)mh->data;
739 struct mipv6_bul_entry *binding = NULL;
741 int msg_len = (mh->length << 3) + 2;
742 int auth = 1, req_auth = 1, refresh = -1, ifindex = 0;
743 u32 lifetime, sequence;
745 if (msg_len < sizeof(*ba)) {
746 DEBUG(DBG_WARNING, "Mobility Header length less than BA");
747 MIPV6_INC_STATS(n_ba_drop.invalid);
751 lifetime = ntohs(ba->lifetime) << 2;
752 sequence = ntohs(ba->sequence);
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)
759 * MIPV6_OPT_AUTH_DATA, MIPV6_OPT_BR_ADVICE
762 refresh = ntohs(opts.br_advice->refresh_interval);
765 if (ba->status >= EXPIRED_HOME_NONCE_INDEX &&
766 ba->status <= EXPIRED_NONCES)
769 write_lock(&bul_lock);
770 binding = mipv6_bul_get(src, home);
772 DEBUG(DBG_INFO, "No binding, BA dropped.");
773 write_unlock(&bul_lock);
777 if (opts.auth_data && binding->rr && (mipv6_auth_check(
778 src, coa, (__u8 *)mh, msg_len, opts.auth_data, binding->rr->kbu) == 0))
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;
788 if (ba->status == SEQUENCE_NUMBER_OUT_OF_WINDOW) {
790 "Sequence number out of window, setting seq to %d",
792 binding->seq = sequence + 1;
793 MIPV6_INC_STATS(n_ban_rcvd);
794 send_bu_msg(binding);
796 write_unlock(&bul_lock);
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;
807 if (ba->status == EXPIRED_HOME_NONCE_INDEX || ba->status == EXPIRED_NONCES) {
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,
814 binding->rr->hot_cookie);
815 MIPV6_INC_STATS(n_ban_rcvd);
817 DEBUG(DBG_WARNING, "Got BA with status EXPIRED_HOME_NONCE_INDEX"
819 MIPV6_INC_STATS(n_ba_drop.invalid);
821 write_unlock(&bul_lock);
824 if (ba->status == EXPIRED_CAREOF_NONCE_INDEX || ba->status == EXPIRED_NONCES) {
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,
831 binding->rr->cot_cookie);
832 MIPV6_INC_STATS(n_ban_rcvd);
834 DEBUG(DBG_WARNING, "Got BA with status EXPIRED_HOME_CAREOF_INDEX"
836 MIPV6_INC_STATS(n_ba_drop.invalid);
838 write_unlock(&bul_lock);
841 write_unlock(&bul_lock);
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);
851 if (ba->status != 0) {
852 /* Unknown BA status */
853 MIPV6_INC_STATS(n_ba_drop.invalid);
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");
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
874 static int mipv6_handle_mh_be(struct in6_addr *home,
875 struct in6_addr *coa,
877 struct in6_addr *unused,
880 struct mipv6_mh_be *be = (struct mipv6_mh_be *)mh->data;
881 int msg_len = (mh->length << 3) + 2;
883 if (msg_len < sizeof(*be)) {
884 DEBUG(DBG_WARNING, "Mobility Header length less than BE");
885 MIPV6_INC_STATS(n_be_drop.invalid);
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;
895 if (msg_len > sizeof(*be)) {
896 /* no valid Mobility Options this time, just ignore */
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
905 mipv6_bul_delete(cn, home);
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
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.
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.
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.
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.
937 * Return Value : 0 on Success, -1 on Failure
939 static int mipv6_bu_rate_limit(struct mipv6_bul_entry *bulentry,
940 struct in6_addr *coa, __u8 flags)
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;
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) {
953 bulentry->consecutive_sends ++;
955 /* Remaining updates SHOULD be sent at SLOW_UPDATE_RATE */
956 if (jiffies - bulentry->lastsend < SLOW_UPDATE_RATE * HZ) {
959 /* Don't inc 'consecutive_sends' to avoid overflow to zero */
961 /* OK to send a BU */
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
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.
992 * Caller may not hold @bul_lock.
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)
1002 int (*callback)(struct mipv6_bul_entry *);
1003 __u32 callback_time;
1004 struct mipv6_bul_entry *bulentry;
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");
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));
1015 if ((bulentry = mipv6_bul_get(daddr, saddr)) != NULL) {
1016 if (bulentry->state == ACK_ERROR) {
1018 * Don't send any more BU's to nodes which don't
1019 * understanding one.
1021 DEBUG(DBG_INFO, "Not sending BU to node which doesn't"
1025 if (mipv6_bu_rate_limit(bulentry, coa, flags) < 0) {
1026 DEBUG(DBG_DATADUMP, "Limiting BU sent.");
1031 switch (mipv6_rr_state(bulentry, saddr, coa, flags)) {
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");
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);
1046 DEBUG(DBG_DATADUMP, "No RR necessary" );
1052 seq = bulentry->seq + 1;
1054 /* Add to binding update list */
1056 if (flags & MIPV6_BU_F_ACK) {
1057 DEBUG(DBG_INFO, "Setting bul callback to bul_resend_exp");
1058 /* Send using exponential backoff */
1060 callback = bul_resend_exp;
1061 callback_time = initdelay;
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;
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,
1076 DEBUG(DBG_INFO, "couldn't update BUL");
1079 ret = send_bu_msg(bulentry);
1084 int __init mipv6_mh_mn_init(void)
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);
1095 void __exit mipv6_mh_mn_exit(void)
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);