Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/crypto/dist/ipsec-tools/src/racoon Netlink deletion notifica...



details:   https://anonhg.NetBSD.org/src/rev/fa28bb87524f
branches:  trunk
changeset: 759242:fa28bb87524f
user:      tteras <tteras%NetBSD.org@localhost>
date:      Fri Dec 03 09:46:24 2010 +0000

description:
Netlink deletion notification does not guarentee actual address deletion:
it might still exist on some other interface. Make sure we do not unbind
unless the address is really gone.

diffstat:

 crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c |  95 ++++++++++++++++++++++++-
 1 files changed, 92 insertions(+), 3 deletions(-)

diffs (145 lines):

diff -r f744d63b45fe -r fa28bb87524f crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c
--- a/crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c   Fri Dec 03 08:42:14 2010 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/grabmyaddr.c   Fri Dec 03 09:46:24 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: grabmyaddr.c,v 1.26 2010/10/22 06:26:26 tteras Exp $   */
+/*     $NetBSD: grabmyaddr.c,v 1.27 2010/12/03 09:46:24 tteras Exp $   */
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * Copyright (C) 2008 Timo Teras <timo.teras%iki.fi@localhost>.
@@ -319,6 +319,11 @@
 
 #if defined(USE_NETLINK)
 
+static int netlink_fd = -1;
+
+#define NLMSG_TAIL(nmsg) \
+       ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
 static void
 parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
 {
@@ -331,6 +336,24 @@
 }
 
 static int
+netlink_add_rtattr_l(struct nlmsghdr *n, int maxlen, int type,
+                    const void *data, int alen)
+{
+       int len = RTA_LENGTH(alen);
+       struct rtattr *rta;
+
+       if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
+               return FALSE;
+
+       rta = NLMSG_TAIL(n);
+       rta->rta_type = type;
+       rta->rta_len = len;
+       memcpy(RTA_DATA(rta), data, alen);
+       n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
+       return TRUE;
+}
+
+static int
 netlink_enumerate(fd, family, type)
        int fd;
        int family;
@@ -410,6 +433,42 @@
 #endif
 
 static int
+netlink_route_is_local(int family, const unsigned char *addr, size_t addr_len)
+{
+       struct {
+               struct nlmsghdr n;
+               struct rtmsg    r;
+               char            buf[1024];
+       } req;
+       struct rtmsg *r = NLMSG_DATA(&req.n);
+       struct rtattr *rta[RTA_MAX+1];
+       struct sockaddr_nl nladdr;
+       ssize_t rlen;
+
+       memset(&req, 0, sizeof(req));
+       req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+       req.n.nlmsg_flags = NLM_F_REQUEST;
+       req.n.nlmsg_type = RTM_GETROUTE;
+       req.r.rtm_family = family;
+       netlink_add_rtattr_l(&req.n, sizeof(req), RTA_DST,
+                            addr, addr_len);
+       req.r.rtm_dst_len = addr_len * 8;
+
+       memset(&nladdr, 0, sizeof(nladdr));
+       nladdr.nl_family = AF_NETLINK;
+
+       if (sendto(netlink_fd, &req, sizeof(req), 0,
+                  (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0)
+               return 0;
+       rlen = recv(netlink_fd, &req, sizeof(req), 0);
+       if (rlen < 0)
+               return 0;
+
+       return  req.n.nlmsg_type == RTM_NEWROUTE &&
+               req.r.rtm_type == RTN_LOCAL;
+}
+
+static int
 netlink_process_route(struct nlmsghdr *h)
 {
        struct sockaddr_storage addr;
@@ -455,6 +514,18 @@
                return 0;
        }
 
+       /* If local route was deleted, check if there is still local
+        * route for the same IP on another interface */
+       if (h->nlmsg_type == RTM_DELROUTE &&
+           netlink_route_is_local(rtm->rtm_family,
+                                  RTA_DATA(rta[RTA_DST]),
+                                  RTA_PAYLOAD(rta[RTA_DST]))) {
+               plog(LLV_DEBUG, LOCATION, NULL,
+                       "Netlink: not deleting %s yet, it exists still\n",
+                       saddrwop2str((struct sockaddr *) &addr));
+               return 0;
+       }
+
        netlink_add_del_address(h->nlmsg_type == RTM_NEWROUTE,
                                (struct sockaddr *) &addr);
        return 0;
@@ -518,9 +589,8 @@
 }
 
 static int
-kernel_open_socket()
+netlink_open_socket()
 {
-       struct sockaddr_nl nl;
        int fd;
 
        fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
@@ -535,6 +605,25 @@
                plog(LLV_WARNING, LOCATION, NULL,
                     "failed to put socket in non-blocking mode\n");
 
+       return fd;
+}
+
+static int
+kernel_open_socket()
+{
+       struct sockaddr_nl nl;
+       int fd;
+
+       if (netlink_fd < 0) {
+               netlink_fd = netlink_open_socket();
+               if (netlink_fd < 0)
+                       return -1;
+       }
+
+       fd = netlink_open_socket();
+       if (fd < 0)
+               return fd;
+
        /* We monitor IPv4 addresses using RTMGRP_IPV4_ROUTE group
         * the get the RTN_LOCAL routes which are automatically added
         * by kernel. This is because:



Home | Main Index | Thread Index | Old Index