kdump/kdump-Routable-preferred-source-address.patch

160 lines
4.8 KiB
Diff

Date: Fri Jun 9 16:46:10 2017 +0200
From: Petr Tesarik <ptesarik@suse.com>
Subject: Routable: parse and store preferred source address
References: FATE#321844
Upstream: v0.8.17
Git-commit: 3748faebf9834eae0a0676800984ebccd7d3cab9
This is the preferred source address, used by the kernel for outgoing
connections when no other address is explicitly set.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
diff --git a/kdumptool/routable.cc b/kdumptool/routable.cc
index d9833f6..6137f89 100644
--- a/kdumptool/routable.cc
+++ b/kdumptool/routable.cc
@@ -58,6 +58,10 @@ class NetLink {
int waitRouteChange(void);
+ const char *prefSrc(void) const
+ throw ()
+ { return m_prefsrc; }
+
protected:
class RecvCheck {
public:
@@ -89,6 +93,8 @@ class NetLink {
throw ()
{ return m_message; }
+ int parseAttrs(const struct rtattr *rta, size_t len);
+
private:
int m_timeout;
@@ -99,13 +105,16 @@ class NetLink {
size_t m_buflen;
unsigned char *m_buffer;
struct nlmsghdr *m_message;
+
+ int m_family;
+ char m_prefsrc[INET6_ADDRSTRLEN];
};
unsigned NetLink::m_seq;
// -----------------------------------------------------------------------------
NetLink::NetLink(unsigned subscribe, size_t recv_max)
- : m_timeout(-1), m_buflen(recv_max)
+ : m_timeout(-1), m_buflen(recv_max), m_family(AF_UNSPEC)
{
struct sockaddr_nl sa;
socklen_t salen;
@@ -126,6 +135,8 @@ NetLink::NetLink(unsigned subscribe, size_t recv_max)
throw KSystemError("Cannot get local netlink address", errno);
if (salen != sizeof m_local || m_local.nl_family != AF_NETLINK)
throw KError("Invalid local netlink address");
+
+ m_prefsrc[0] = '\0';
}
// -----------------------------------------------------------------------------
@@ -354,7 +365,8 @@ int NetLink::checkRoute(const struct addrinfo *ai)
case RTN_BROADCAST:
case RTN_ANYCAST:
case RTN_MULTICAST:
- return 0;
+ m_family = rt->rtm_family;
+ return parseAttrs(RTM_RTA(rt), RTM_PAYLOAD(nh));
case RTN_UNREACHABLE:
return -EHOSTUNREACH;
case RTN_BLACKHOLE:
@@ -368,6 +380,49 @@ int NetLink::checkRoute(const struct addrinfo *ai)
}
}
+// -----------------------------------------------------------------------------
+int NetLink::parseAttrs(const struct rtattr *rta, size_t len)
+{
+ while (RTA_OK(rta, len)) {
+ void *data = RTA_DATA(rta);
+ size_t dlen = RTA_PAYLOAD(rta);
+ int res;
+
+ switch (rta->rta_type) {
+ case RTA_PREFSRC:
+ if (m_family == AF_INET &&
+ dlen == sizeof(struct in_addr)) {
+ struct sockaddr_in saddr;
+ memset(&saddr, 0, sizeof saddr);
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr = *(struct in_addr *)data;
+ res = getnameinfo((struct sockaddr*)&saddr, sizeof saddr,
+ m_prefsrc, sizeof m_prefsrc,
+ NULL, 0, NI_NUMERICHOST);
+ } else if (m_family == AF_INET6 &&
+ dlen == sizeof(struct in6_addr)) {
+ struct sockaddr_in6 saddr;
+ memset(&saddr, 0, sizeof saddr);
+ saddr.sin6_family = AF_INET6;
+ saddr.sin6_addr = *(struct in6_addr *)data;
+ res = getnameinfo((struct sockaddr*)&saddr, sizeof saddr,
+ m_prefsrc, sizeof m_prefsrc,
+ NULL, 0, NI_NUMERICHOST);
+ } else
+ res = EAI_FAMILY;
+ if (res)
+ throw KGaiError("Cannot parse preferred source address", res);
+
+ break;
+ }
+ rta = RTA_NEXT(rta, len);
+ }
+ if (len)
+ throw KError("Netlink rtattr truncated");
+
+ return 0;
+}
+
//}}}
//{{{ Routable -----------------------------------------------------------------
@@ -388,8 +443,11 @@ bool Routable::hasRoute(void)
Debug::debug()->trace("hasRoute(%s)", m_host.c_str());
for (p = m_ai; p; p = p->ai_next) {
- if (nl.checkRoute(p) == 0)
+ if (nl.checkRoute(p) == 0) {
+ Debug::debug()->dbg("m_prefsrc='%s'", nl.prefSrc());
+ m_prefsrc.assign(nl.prefSrc());
return true;
+ }
}
return false;
diff --git a/kdumptool/routable.h b/kdumptool/routable.h
index cdfffaf..0763131 100644
--- a/kdumptool/routable.h
+++ b/kdumptool/routable.h
@@ -42,6 +42,10 @@ class Routable {
bool check(int timeout);
+ const std::string& prefsrc(void) const
+ throw ()
+ { return m_prefsrc; }
+
protected:
bool resolve(void)
throw (KError);
@@ -51,6 +55,7 @@ class Routable {
private:
int m_nlfd;
std::string m_host;
+ std::string m_prefsrc;
struct addrinfo *m_ai;
};