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

« back to all changes in this revision

Viewing changes to keepalived/vrrp/vrrp_netlink.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-05-12 20:26:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090512202615-k850bw35qpuvpq4p
Tags: 1.1.17-1ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/rules: DEB_UPDATE_RCD_PARAMS := expicit init start/stop
    parameters (don't stop at 0 and 6)
  - debian/init.d: init script header adapted to stop rule
  - debian/keepalived.postinst: Remove shutdown and reboot links

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * Part:        NETLINK kernel command channel.
7
7
 *
8
 
 * Version:     $Id: vrrp_netlink.c,v 1.1.15 2007/09/15 04:07:41 acassen Exp $
 
8
 * Version:     $Id: vrrp_netlink.c,v 1.1.17 2009/03/05 01:31:12 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-2007 Alexandre Cassen, <acassen@freebox.fr>
 
22
 * Copyright (C) 2001-2009 Alexandre Cassen, <acassen@freebox.fr>
23
23
 */
24
24
 
25
25
/* global include */
40
40
#include "check_api.h"
41
41
#include "vrrp_netlink.h"
42
42
#include "vrrp_if.h"
 
43
#include "logger.h"
43
44
#include "memory.h"
44
45
#include "scheduler.h"
45
46
#include "utils.h"
52
53
int
53
54
netlink_socket(struct nl_handle *nl, unsigned long groups)
54
55
{
55
 
        int addr_len;
 
56
        socklen_t addr_len;
56
57
        int ret;
57
58
 
58
59
        memset(nl, 0, sizeof (nl));
59
60
 
60
61
        nl->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
61
62
        if (nl->fd < 0) {
62
 
                syslog(LOG_INFO, "Netlink: Cannot open netlink socket : (%s)",
 
63
                log_message(LOG_INFO, "Netlink: Cannot open netlink socket : (%s)",
63
64
                       strerror(errno));
64
65
                return -1;
65
66
        }
66
67
 
67
68
        ret = fcntl(nl->fd, F_SETFL, O_NONBLOCK);
68
69
        if (ret < 0) {
69
 
                syslog(LOG_INFO,
 
70
                log_message(LOG_INFO,
70
71
                       "Netlink: Cannot set netlink socket flags : (%s)",
71
72
                       strerror(errno));
72
73
                close(nl->fd);
79
80
 
80
81
        ret = bind(nl->fd, (struct sockaddr *) &nl->snl, sizeof (nl->snl));
81
82
        if (ret < 0) {
82
 
                syslog(LOG_INFO, "Netlink: Cannot bind netlink socket : (%s)",
 
83
                log_message(LOG_INFO, "Netlink: Cannot bind netlink socket : (%s)",
83
84
                       strerror(errno));
84
85
                close(nl->fd);
85
86
                return -1;
88
89
        addr_len = sizeof (nl->snl);
89
90
        ret = getsockname(nl->fd, (struct sockaddr *) &nl->snl, &addr_len);
90
91
        if (ret < 0 || addr_len != sizeof (nl->snl)) {
91
 
                syslog(LOG_INFO, "Netlink: Cannot getsockname : (%s)",
 
92
                log_message(LOG_INFO, "Netlink: Cannot getsockname : (%s)",
92
93
                       strerror(errno));
93
94
                close(nl->fd);
94
95
                return -1;
95
96
        }
96
97
 
97
98
        if (nl->snl.nl_family != AF_NETLINK) {
98
 
                syslog(LOG_INFO, "Netlink: Wrong address family %d",
 
99
                log_message(LOG_INFO, "Netlink: Wrong address family %d",
99
100
                       nl->snl.nl_family);
100
101
                close(nl->fd);
101
102
                return -1;
119
120
netlink_set_block(struct nl_handle *nl, int *flags)
120
121
{
121
122
        if ((*flags = fcntl(nl->fd, F_GETFL, 0)) < 0) {
122
 
                syslog(LOG_INFO, "Netlink: Cannot F_GETFL socket : (%s)",
 
123
                log_message(LOG_INFO, "Netlink: Cannot F_GETFL socket : (%s)",
123
124
                       strerror(errno));
124
125
                return -1;
125
126
        }
126
127
        *flags &= ~O_NONBLOCK;
127
128
        if (fcntl(nl->fd, F_SETFL, *flags) < 0) {
128
 
                syslog(LOG_INFO, "Netlink: Cannot F_SETFL socket : (%s)",
 
129
                log_message(LOG_INFO, "Netlink: Cannot F_SETFL socket : (%s)",
129
130
                       strerror(errno));
130
131
                return -1;
131
132
        }
138
139
{
139
140
        *flags |= O_NONBLOCK;
140
141
        if (fcntl(nl->fd, F_SETFL, *flags) < 0) {
141
 
                syslog(LOG_INFO, "Netlink: Cannot F_SETFL socket : (%s)",
 
142
                log_message(LOG_INFO, "Netlink: Cannot F_SETFL socket : (%s)",
142
143
                       strerror(errno));
143
144
                return -1;
144
145
        }
179
180
        return 0;
180
181
}
181
182
 
 
183
int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
 
184
                  const void *data, int alen)
 
185
{
 
186
        struct rtattr *subrta;
 
187
        int len = RTA_LENGTH(alen);
 
188
 
 
189
        if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) {
 
190
                return -1;
 
191
        }
 
192
        subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
 
193
        subrta->rta_type = type;
 
194
        subrta->rta_len = len;
 
195
        memcpy(RTA_DATA(subrta), data, alen);
 
196
        rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len);
 
197
        return 0;
 
198
}
 
199
 
182
200
static void
183
201
parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
184
202
{
245
263
                                continue;
246
264
                        if (errno == EWOULDBLOCK || errno == EAGAIN)
247
265
                                break;
248
 
                        syslog(LOG_INFO, "Netlink: Received message overrun");
 
266
                        log_message(LOG_INFO, "Netlink: Received message overrun");
249
267
                        continue;
250
268
                }
251
269
 
252
270
                if (status == 0) {
253
 
                        syslog(LOG_INFO, "Netlink: EOF");
 
271
                        log_message(LOG_INFO, "Netlink: EOF");
254
272
                        return -1;
255
273
                }
256
274
 
257
275
                if (msg.msg_namelen != sizeof snl) {
258
 
                        syslog(LOG_INFO,
 
276
                        log_message(LOG_INFO,
259
277
                               "Netlink: Sender address length error: length %d",
260
278
                               msg.msg_namelen);
261
279
                        return -1;
282
300
                                }
283
301
 
284
302
                                if (h->nlmsg_len < NLMSG_LENGTH(sizeof (struct nlmsgerr))) {
285
 
                                        syslog(LOG_INFO,
 
303
                                        log_message(LOG_INFO,
286
304
                                               "Netlink: error: message truncated");
287
305
                                        return -1;
288
306
                                }
289
 
                                syslog(LOG_INFO,
 
307
                                log_message(LOG_INFO,
290
308
                                       "Netlink: error: %s, type=(%u), seq=%u, pid=%d",
291
309
                                       strerror(-err->error),
292
310
                                       err->msg.nlmsg_type,
297
315
 
298
316
                        /* Skip unsolicited messages from cmd channel */
299
317
                        if (nl != &nl_cmd && h->nlmsg_pid == nl_cmd.snl.nl_pid) {
300
 
                                syslog(LOG_INFO, "Netlink: skipping nl_cmd msg...");
 
318
                                log_message(LOG_INFO, "Netlink: skipping nl_cmd msg...");
301
319
                                continue;
302
320
                        }
303
321
 
304
322
                        error = (*filter) (&snl, h);
305
323
                        if (error < 0) {
306
 
                                syslog(LOG_INFO,
 
324
                                log_message(LOG_INFO,
307
325
                                       "Netlink: filter function error");
308
326
                                ret = error;
309
327
                        }
311
329
 
312
330
                /* After error care. */
313
331
                if (msg.msg_flags & MSG_TRUNC) {
314
 
                        syslog(LOG_INFO, "Netlink: error: message truncated");
 
332
                        log_message(LOG_INFO, "Netlink: error: message truncated");
315
333
                        continue;
316
334
                }
317
335
                if (status) {
318
 
                        syslog(LOG_INFO, "Netlink: error: data remnant size %d",
 
336
                        log_message(LOG_INFO, "Netlink: error: data remnant size %d",
319
337
                               status);
320
338
                        return -1;
321
339
                }
328
346
static int
329
347
netlink_talk_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
330
348
{
331
 
        syslog(LOG_INFO, "Netlink: ignoring message type 0x%04x",
 
349
        log_message(LOG_INFO, "Netlink: ignoring message type 0x%04x",
332
350
               h->nlmsg_type);
333
351
        return 0;
334
352
}
354
372
        /* Send message to netlink interface. */
355
373
        status = sendmsg(nl->fd, &msg, 0);
356
374
        if (status < 0) {
357
 
                syslog(LOG_INFO, "Netlink: sendmsg() error: %s",
 
375
                log_message(LOG_INFO, "Netlink: sendmsg() error: %s",
358
376
                       strerror(errno));
359
377
                return -1;
360
378
        }
362
380
        /* Set blocking flag */
363
381
        ret = netlink_set_block(nl, &flags);
364
382
        if (ret < 0)
365
 
                syslog(LOG_INFO, "Netlink: Warning, couldn't set "
 
383
                log_message(LOG_INFO, "Netlink: Warning, couldn't set "
366
384
                       "blocking flag to netlink socket...");
367
385
 
368
386
        status = netlink_parse_info(netlink_talk_filter, nl);
398
416
        status = sendto(nl->fd, (void *) &req, sizeof (req)
399
417
                        , 0, (struct sockaddr *) &snl, sizeof (snl));
400
418
        if (status < 0) {
401
 
                syslog(LOG_INFO, "Netlink: sendto() failed: %s",
 
419
                log_message(LOG_INFO, "Netlink: sendto() failed: %s",
402
420
                       strerror(errno));
403
421
                return -1;
404
422
        }
447
465
                int hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
448
466
 
449
467
                if (hw_addr_len > IF_HWADDR_MAX)
450
 
                        syslog(LOG_ERR, "MAC address for %s is too large: %d",
 
468
                        log_message(LOG_ERR, "MAC address for %s is too large: %d",
451
469
                               name, hw_addr_len);
452
470
                else {
453
471
                        ifp->hw_addr_len = hw_addr_len;
541
559
        /* Set blocking flag */
542
560
        ret = netlink_set_block(&nlh, &flags);
543
561
        if (ret < 0)
544
 
                syslog(LOG_INFO, "Netlink: 1Warning, couldn't set "
 
562
                log_message(LOG_INFO, "Netlink: 1Warning, couldn't set "
545
563
                       "blocking flag to netlink socket...");
546
564
 
547
565
        /* Interface lookup */
570
588
        /* Set blocking flag */
571
589
        ret = netlink_set_block(&nlh, &flags);
572
590
        if (ret < 0)
573
 
                syslog(LOG_INFO, "Netlink: 2Warning, couldn't set "
 
591
                log_message(LOG_INFO, "Netlink: 2Warning, couldn't set "
574
592
                       "blocking flag to netlink socket...");
575
593
 
576
594
        /* Address lookup */
637
655
                return netlink_if_address_filter(snl, h);
638
656
                break;
639
657
        default:
640
 
                syslog(LOG_INFO,
 
658
                log_message(LOG_INFO,
641
659
                       "Kernel is reflecting an unknown netlink nlmsg_type: %d",
642
660
                       h->nlmsg_type);
643
661
                break;
674
692
        netlink_socket(&nl_kernel, groups);
675
693
 
676
694
        if (nl_kernel.fd > 0) {
677
 
                syslog(LOG_INFO, "Registering Kernel netlink reflector");
 
695
                log_message(LOG_INFO, "Registering Kernel netlink reflector");
678
696
                thread_add_read(master, kernel_netlink, NULL, nl_kernel.fd,
679
697
                                NETLINK_TIMER);
680
698
        } else
681
 
                syslog(LOG_INFO, "Error while registering Kernel netlink reflector channel");
 
699
                log_message(LOG_INFO, "Error while registering Kernel netlink reflector channel");
682
700
 
683
701
        /* Prepare netlink command channel. */
684
702
        netlink_socket(&nl_cmd, 0);
685
703
        if (nl_cmd.fd > 0)
686
 
                syslog(LOG_INFO, "Registering Kernel netlink command channel");
 
704
                log_message(LOG_INFO, "Registering Kernel netlink command channel");
687
705
        else
688
 
                syslog(LOG_INFO, "Error while registering Kernel netlink cmd channel");
 
706
                log_message(LOG_INFO, "Error while registering Kernel netlink cmd channel");
689
707
}
690
708
 
691
709
void