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