~ubuntu-branches/ubuntu/trusty/keepalived/trusty

« back to all changes in this revision

Viewing changes to keepalived/vrrp/vrrp_scheduler.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Wirt
  • Date: 2005-04-29 23:22:40 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050429232240-a8m3jtpi3cvuyyy2
Tags: 1.1.11-3
Added a warning about sarge kernels to README.Debian and 
the package description 

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * Part:        Sheduling framework for vrrp code.
7
7
 *
8
 
 * Version:     $Id: vrrp_scheduler.c,v 1.1.7 2004/04/04 23:28:05 acassen Exp $
 
8
 * Version:     $Id: vrrp_scheduler.c,v 1.1.11 2005/03/01 01:22:13 acassen Exp $
9
9
 *
10
10
 * Author:      Alexandre Cassen, <acassen@linux-vs.org>
11
11
 *
19
19
 *              as published by the Free Software Foundation; either version
20
20
 *              2 of the License, or (at your option) any later version.
21
21
 *
22
 
 * Copyright (C) 2001-2004 Alexandre Cassen, <acassen@linux-vs.org>
 
22
 * Copyright (C) 2001-2005 Alexandre Cassen, <acassen@linux-vs.org>
23
23
 */
24
24
 
25
25
#include "vrrp_scheduler.h"
34
34
#include "ipvswrapper.h"
35
35
#include "memory.h"
36
36
#include "list.h"
 
37
#include "main.h"
37
38
#include "smtp.h"
38
39
 
39
 
/* Externals vars */
40
 
extern thread_master *master;
41
 
extern vrrp_conf_data *vrrp_data;
42
 
extern unsigned int debug;
43
 
 
44
40
/* VRRP FSM (Finite State Machine) design.
45
41
 *
46
42
 * The state transition diagram implemented is :
141
137
{
142
138
        if (vrrp->smtp_alert) {
143
139
                if (vrrp->state == VRRP_STATE_MAST)
144
 
                        smtp_alert(master, NULL, vrrp, NULL,
 
140
                        smtp_alert(NULL, vrrp, NULL,
145
141
                                   "Entering MASTER state",
146
142
                                   "=> VRRP Instance is now owning VRRP VIPs <=");
147
143
                if (vrrp->state == VRRP_STATE_BACK)
148
 
                        smtp_alert(master, NULL, vrrp, NULL,
 
144
                        smtp_alert(NULL, vrrp, NULL,
149
145
                                   "Entering BACKUP state",
150
146
                                   "=> VRRP Instance is nolonger owning VRRP VIPs <=");
151
147
        }
206
202
                               vrrp->iname);
207
203
 
208
204
                        /* Set BACKUP state */
 
205
                        vrrp_restore_interface(vrrp, 0);
209
206
                        vrrp->state = VRRP_STATE_BACK;
210
207
                        vrrp_smtp_notifier(vrrp);
211
208
                        notify_instance_exec(vrrp, VRRP_STATE_BACK);
294
291
static void
295
292
vrrp_register_workers(list l)
296
293
{
297
 
        sock *sock;
 
294
        sock *sock_obj;
298
295
        TIMEVAL timer;
299
296
        long vrrp_timer = 0;
300
297
        element e;
310
307
 
311
308
        /* Register VRRP workers threads */
312
309
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
313
 
                sock = ELEMENT_DATA(e);
 
310
                sock_obj = ELEMENT_DATA(e);
314
311
                /* jump to asynchronous handling */
315
 
                vrrp_timer = vrrp_timer_fd(sock->fd_in);
 
312
                vrrp_timer = vrrp_timer_fd(sock_obj->fd_in);
316
313
 
317
314
                /* Register a timer thread if interface is shut */
318
 
                if (sock->fd_in == -1)
 
315
                if (sock_obj->fd_in == -1)
319
316
                        thread_add_timer(master, vrrp_read_dispatcher_thread,
320
317
                                         (int *)THREAD_TIMER, vrrp_timer);
321
318
                else
322
319
                        thread_add_read(master, vrrp_read_dispatcher_thread,
323
 
                                        NULL, sock->fd_in, vrrp_timer);
 
320
                                        NULL, sock_obj->fd_in, vrrp_timer);
324
321
        }
325
322
}
326
323
 
328
325
static int
329
326
already_exist_sock(list l, int ifindex, int proto)
330
327
{
331
 
        sock *sock;
 
328
        sock *sock_obj;
332
329
        element e;
333
330
 
334
331
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
335
 
                sock = ELEMENT_DATA(e);
336
 
                if ((sock->ifindex == ifindex) && (sock->proto == proto))
 
332
                sock_obj = ELEMENT_DATA(e);
 
333
                if ((sock_obj->ifindex == ifindex) && (sock_obj->proto == proto))
337
334
                        return 1;
338
335
        }
339
336
        return 0;
340
337
}
341
338
 
342
 
/* sockpool list primitives */
343
 
void
344
 
free_sock(void *data)
345
 
{
346
 
        FREE(data);
347
 
}
348
 
 
349
 
void
350
 
dump_sock(void *data)
351
 
{
352
 
        sock *sock = data;
353
 
        syslog(LOG_INFO, "VRRP sockpool: [ifindex(%d), proto(%d), fd(%d,%d)]",
354
 
               sock->ifindex
355
 
               , sock->proto
356
 
               , sock->fd_in
357
 
               , sock->fd_out);
358
 
}
359
 
 
360
339
void
361
340
alloc_sock(list l, int ifindex, int proto)
362
341
{
395
374
static void
396
375
vrrp_open_sockpool(list l)
397
376
{
398
 
        sock *sock;
 
377
        sock *sock_obj;
399
378
        element e;
400
379
 
401
380
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
402
 
                sock = ELEMENT_DATA(e);
403
 
                sock->fd_in = open_vrrp_socket(sock->proto, sock->ifindex);
404
 
                if (sock->fd_in == -1)
405
 
                        sock->fd_out = -1;
 
381
                sock_obj = ELEMENT_DATA(e);
 
382
                sock_obj->fd_in = open_vrrp_socket(sock_obj->proto, sock_obj->ifindex);
 
383
                if (sock_obj->fd_in == -1)
 
384
                        sock_obj->fd_out = -1;
406
385
                else
407
 
                        sock->fd_out = open_vrrp_send_socket(sock->proto,
408
 
                                                             sock->ifindex);
 
386
                        sock_obj->fd_out = open_vrrp_send_socket(sock_obj->proto,
 
387
                                                             sock_obj->ifindex);
409
388
        }
410
389
}
411
390
 
412
391
static void
413
392
vrrp_set_fds(list l)
414
393
{
415
 
        sock *sock;
 
394
        sock *sock_obj;
416
395
        vrrp_rt *vrrp;
417
396
        list p = vrrp_data->vrrp;
418
397
        element e_sock;
420
399
        int proto;
421
400
 
422
401
        for (e_sock = LIST_HEAD(l); e_sock; ELEMENT_NEXT(e_sock)) {
423
 
                sock = ELEMENT_DATA(e_sock);
 
402
                sock_obj = ELEMENT_DATA(e_sock);
424
403
                for (e_vrrp = LIST_HEAD(p); e_vrrp; ELEMENT_NEXT(e_vrrp)) {
425
404
                        vrrp = ELEMENT_DATA(e_vrrp);
426
405
                        if (vrrp->auth_type == VRRP_AUTH_AH)
428
407
                        else
429
408
                                proto = IPPROTO_VRRP;
430
409
 
431
 
                        if ((sock->ifindex == IF_INDEX(vrrp->ifp)) &&
432
 
                            (sock->proto == proto)) {
433
 
                                vrrp->fd_in = sock->fd_in;
434
 
                                vrrp->fd_out = sock->fd_out;
 
410
                        if ((sock_obj->ifindex == IF_INDEX(vrrp->ifp)) &&
 
411
                            (sock_obj->proto == proto)) {
 
412
                                vrrp->fd_in = sock_obj->fd_in;
 
413
                                vrrp->fd_out = sock_obj->fd_out;
435
414
 
436
415
                                /* append to hash index */
437
416
                                alloc_vrrp_fd_bucket(vrrp);
455
434
 * multiplexing points.
456
435
 */
457
436
int
458
 
vrrp_dispatcher_init(thread * thread)
 
437
vrrp_dispatcher_init(thread * thread_obj)
459
438
{
460
 
        list pool;
461
 
 
462
 
        /* allocate the sockpool */
463
 
        pool = alloc_list(free_sock, dump_sock);
464
 
 
465
439
        /* create the VRRP socket pool list */
466
 
        vrrp_create_sockpool(pool);
 
440
        vrrp_create_sockpool(vrrp_data->vrrp_socket_pool);
467
441
 
468
442
        /* open the VRRP socket pool */
469
 
        vrrp_open_sockpool(pool);
 
443
        vrrp_open_sockpool(vrrp_data->vrrp_socket_pool);
470
444
 
471
445
        /* set VRRP instance fds to sockpool */
472
 
        vrrp_set_fds(pool);
 
446
        vrrp_set_fds(vrrp_data->vrrp_socket_pool);
473
447
 
474
448
        /* register read dispatcher worker thread */
475
 
        vrrp_register_workers(pool);
 
449
        vrrp_register_workers(vrrp_data->vrrp_socket_pool);
476
450
 
477
 
        /* cleanup the temp socket pool */
 
451
        /* Dump socket pool */
478
452
        if (debug & 32)
479
 
                dump_list(pool);
480
 
        free_list(pool);
481
 
 
 
453
                dump_list(vrrp_data->vrrp_socket_pool);
482
454
        return 1;
483
455
}
484
456
 
 
457
void
 
458
vrrp_dispatcher_release(vrrp_conf_data *conf_data_obj)
 
459
{
 
460
        free_list(conf_data_obj->vrrp_socket_pool);
 
461
}
 
462
 
485
463
static void
486
 
vrrp_backup(vrrp_rt * vrrp, char *vrrp_buffer, int len)
 
464
vrrp_backup(vrrp_rt * vrrp, char *buffer, int len)
487
465
{
488
 
        struct iphdr *iph = (struct iphdr *) vrrp_buffer;
 
466
        struct iphdr *iph = (struct iphdr *) buffer;
489
467
        ipsec_ah *ah;
490
468
 
491
469
        if (iph->protocol == IPPROTO_IPSEC_AH) {
492
 
                ah = (ipsec_ah *) (vrrp_buffer + sizeof (struct iphdr));
493
 
                if (ah->seq_number >= vrrp->ipsecah_counter->seq_number) {
494
 
//                      vrrp->ipsecah_counter->seq_number = ah->seq_number + 10;
 
470
                ah = (ipsec_ah *) (buffer + sizeof (struct iphdr));
 
471
                if (ntohl(ah->seq_number) >= vrrp->ipsecah_counter->seq_number)
495
472
                        vrrp->ipsecah_counter->cycle = 0;
496
 
                }
497
473
        }
498
474
 
499
 
        vrrp_state_backup(vrrp, vrrp_buffer, len);
 
475
        vrrp_state_backup(vrrp, buffer, len);
500
476
}
501
477
 
502
478
static void
503
 
vrrp_become_master(vrrp_rt * vrrp, char *vrrp_buffer, int len)
 
479
vrrp_become_master(vrrp_rt * vrrp, char *buffer, int len)
504
480
{
505
 
        struct iphdr *iph = (struct iphdr *) vrrp_buffer;
 
481
        struct iphdr *iph = (struct iphdr *) buffer;
506
482
        ipsec_ah *ah;
507
483
 
508
484
        /*
512
488
        if (iph->protocol == IPPROTO_IPSEC_AH) {
513
489
                syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : seq_num sync",
514
490
                       vrrp->iname);
515
 
                ah = (ipsec_ah *) (vrrp_buffer + sizeof (struct iphdr));
516
 
                vrrp->ipsecah_counter->seq_number = ah->seq_number + 1;
 
491
                ah = (ipsec_ah *) (buffer + sizeof (struct iphdr));
 
492
                vrrp->ipsecah_counter->seq_number = ntohl(ah->seq_number) + 1;
517
493
                vrrp->ipsecah_counter->cycle = 0;
518
494
        }
519
495
 
523
499
}
524
500
 
525
501
static void
526
 
vrrp_leave_master(vrrp_rt * vrrp, char *vrrp_buffer, int len)
 
502
vrrp_leave_master(vrrp_rt * vrrp, char *buffer, int len)
527
503
{
528
504
        if (!VRRP_ISUP(vrrp)) {
529
505
                vrrp_log_int_down(vrrp);
530
506
                vrrp->wantstate = VRRP_STATE_GOTO_FAULT;
531
507
                vrrp_state_leave_master(vrrp);
532
 
        } else if (vrrp_state_master_rx(vrrp, vrrp_buffer, len)) {
 
508
        } else if (vrrp_state_master_rx(vrrp, buffer, len)) {
533
509
                vrrp_state_leave_master(vrrp);
534
510
                vrrp_smtp_notifier(vrrp);
535
511
        }
549
525
}
550
526
 
551
527
static void
552
 
vrrp_leave_fault(vrrp_rt * vrrp, char *vrrp_buffer, int len)
 
528
vrrp_leave_fault(vrrp_rt * vrrp, char *buffer, int len)
553
529
{
554
530
        if (!VRRP_ISUP(vrrp))
555
531
                return;
556
532
 
557
 
        if (vrrp_state_fault_rx(vrrp, vrrp_buffer, len)) {
 
533
        if (vrrp_state_fault_rx(vrrp, buffer, len)) {
558
534
                if (vrrp->sync) {
559
535
                        if (vrrp_sync_leave_fault(vrrp)) {
560
536
                                syslog(LOG_INFO,
561
537
                                       "VRRP_Instance(%s) prio is higher than received advert",
562
538
                                       vrrp->iname);
563
 
                                vrrp_become_master(vrrp, vrrp_buffer, len);
 
539
                                vrrp_become_master(vrrp, buffer, len);
564
540
                        }
565
541
                } else {
566
542
                        syslog(LOG_INFO,
567
543
                               "VRRP_Instance(%s) prio is higher than received advert",
568
544
                               vrrp->iname);
569
 
                        vrrp_become_master(vrrp, vrrp_buffer, len);
 
545
                        vrrp_become_master(vrrp, buffer, len);
570
546
                }
571
547
        } else {
572
548
                if (vrrp->sync) {
610
586
 
611
587
/* Delayed gratuitous ARP thread */
612
588
int
613
 
vrrp_gratuitous_arp_thread(thread * thread)
 
589
vrrp_gratuitous_arp_thread(thread * thread_obj)
614
590
{
615
 
        vrrp_rt *vrrp = THREAD_ARG(thread);
 
591
        vrrp_rt *vrrp = THREAD_ARG(thread_obj);
616
592
 
617
593
        /* Simply broadcast the gratuitous ARP */
618
594
        vrrp_send_gratuitous_arp(vrrp);
671
647
        vrrp_sgroup *vgroup = vrrp->sync;
672
648
 
673
649
        if (vgroup) {
674
 
                if (vrrp_sync_leave_fault(vrrp)) {
675
 
                        if (vgroup->state == VRRP_STATE_FAULT)
676
 
                                vgroup->state = vrrp->init_state;
677
 
                } else
 
650
                if (!vrrp_sync_leave_fault(vrrp))
678
651
                        return;
679
652
        } else if (VRRP_ISUP(vrrp))
680
653
                vrrp_log_int_up(vrrp);
788
761
 
789
762
/* Our read packet dispatcher */
790
763
int
791
 
vrrp_read_dispatcher_thread(thread * thread)
 
764
vrrp_read_dispatcher_thread(thread * thread_obj)
792
765
{
793
766
        long vrrp_timer = 0;
794
767
        int fd;
795
768
 
796
769
        /* Dispatcher state handler */
797
 
        if (thread->type == THREAD_READ_TIMEOUT)
798
 
                fd = vrrp_dispatcher_read_to(thread->u.fd);
799
 
        else if (thread->arg) {
 
770
        if (thread_obj->type == THREAD_READ_TIMEOUT)
 
771
                fd = vrrp_dispatcher_read_to(thread_obj->u.fd);
 
772
        else if (thread_obj->arg) {
800
773
                fd = vrrp_dispatcher_read_to(-1);
801
774
        } else
802
 
                fd = vrrp_dispatcher_read(thread->u.fd);
 
775
                fd = vrrp_dispatcher_read(thread_obj->u.fd);
803
776
 
804
777
        /* register next dispatcher thread */
805
778
        vrrp_timer = vrrp_timer_fd(fd);
806
779
        if (fd == -1)
807
 
                thread_add_timer(thread->master, vrrp_read_dispatcher_thread,
 
780
                thread_add_timer(thread_obj->master, vrrp_read_dispatcher_thread,
808
781
                                 (int *)THREAD_TIMER, vrrp_timer);
809
782
        else
810
 
                thread_add_read(thread->master, vrrp_read_dispatcher_thread,
 
783
                thread_add_read(thread_obj->master, vrrp_read_dispatcher_thread,
811
784
                                NULL, fd, vrrp_timer);
812
785
 
813
786
        return 0;