Netlink module supports interface scan on startup. Working on more.
This commit is contained in:
parent
e35ef181a4
commit
7972248d5d
2 changed files with 123 additions and 8 deletions
6
TODO
6
TODO
|
@ -19,12 +19,12 @@ Core
|
|||
|
||||
- incoming packets: interface the packet came from? (esp. for multicasts)
|
||||
- broadcast/multicast echoing suppresion
|
||||
- we need ifindex at least for PtP links
|
||||
|
||||
- kernel: RTM_DELROUTE not announced for device routes [confirmed by Alexey: it's a feature]
|
||||
|
||||
- netlink: import Linux route attributes to our rta's, so that they can be filtered?
|
||||
|
||||
- iface: when seen an invalid broadcast, fix it up or at least report
|
||||
- iface: we always need ifindex at least for PtP links (OSPF)
|
||||
|
||||
Cleanup
|
||||
~~~~~~~
|
||||
- right usage of DBG vs. debug
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
|
@ -102,6 +103,11 @@ nl_get_reply(void)
|
|||
int x = recvmsg(nl_sync_fd, &m, 0);
|
||||
if (x < 0)
|
||||
die("nl_get_reply: %m");
|
||||
if (sa.nl_pid) /* It isn't from the kernel */
|
||||
{
|
||||
DBG("Non-kernel packet\n");
|
||||
continue;
|
||||
}
|
||||
nl_last_size = x;
|
||||
nl_last_hdr = (void *) nl_rx_buffer;
|
||||
if (m.msg_flags & MSG_TRUNC)
|
||||
|
@ -193,14 +199,63 @@ nl_parse_attrs(struct rtattr *a, struct rtattr **k, int ksize)
|
|||
*/
|
||||
|
||||
static void
|
||||
nl_parse_link(struct nlmsghdr *h)
|
||||
nl_parse_link(struct nlmsghdr *h, int scan)
|
||||
{
|
||||
struct ifinfomsg *i;
|
||||
struct rtattr *a[IFLA_STATS+1];
|
||||
int new = h->nlmsg_type == RTM_NEWLINK;
|
||||
struct iface f;
|
||||
struct iface *ifi;
|
||||
char *name;
|
||||
u32 mtu;
|
||||
unsigned int fl;
|
||||
|
||||
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFLA_RTA(i), a, sizeof(a)))
|
||||
return;
|
||||
DBG("NEWLINK %d\n", i->ifi_index);
|
||||
if (!a[IFLA_IFNAME] || RTA_PAYLOAD(a[IFLA_IFNAME]) < 2 ||
|
||||
!a[IFLA_MTU] || RTA_PAYLOAD(a[IFLA_MTU]) != 4)
|
||||
{
|
||||
log(L_ERR "nl_parse_link: Malformed message received");
|
||||
return;
|
||||
}
|
||||
name = RTA_DATA(a[IFLA_IFNAME]);
|
||||
memcpy(&mtu, RTA_DATA(a[IFLA_MTU]), sizeof(u32));
|
||||
|
||||
ifi = if_find_by_index(i->ifi_index);
|
||||
if (!new)
|
||||
{
|
||||
DBG("KRT: IF%d(%s) goes down\n", i->ifi_index, name);
|
||||
if (ifi && !scan)
|
||||
{
|
||||
memcpy(&f, ifi, sizeof(struct iface));
|
||||
f.flags |= IF_ADMIN_DOWN;
|
||||
if_update(&f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("KRT: IF%d(%s) goes up (mtu=%d,flg=%x)\n", i->ifi_index, name, mtu, i->ifi_flags);
|
||||
if (ifi)
|
||||
memcpy(&f, ifi, sizeof(f));
|
||||
else
|
||||
{
|
||||
bzero(&f, sizeof(f));
|
||||
f.index = i->ifi_index;
|
||||
}
|
||||
strncpy(f.name, RTA_DATA(a[IFLA_IFNAME]), sizeof(f.name)-1);
|
||||
f.mtu = mtu;
|
||||
f.flags = 0;
|
||||
fl = i->ifi_flags;
|
||||
if (fl & IFF_UP)
|
||||
f.flags |= IF_LINK_UP;
|
||||
if (fl & IFF_POINTOPOINT)
|
||||
f.flags |= IF_UNNUMBERED | IF_MULTICAST;
|
||||
if (fl & IFF_LOOPBACK)
|
||||
f.flags |= IF_LOOPBACK | IF_IGNORE;
|
||||
if (fl & IFF_BROADCAST)
|
||||
f.flags |= IF_BROADCAST | IF_MULTICAST;
|
||||
if_update(&f);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -208,10 +263,68 @@ nl_parse_addr(struct nlmsghdr *h)
|
|||
{
|
||||
struct ifaddrmsg *i;
|
||||
struct rtattr *a[IFA_ANYCAST+1];
|
||||
int new = h->nlmsg_type == RTM_NEWADDR;
|
||||
struct iface f;
|
||||
struct iface *ifi;
|
||||
|
||||
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a)))
|
||||
return;
|
||||
DBG("NEWADDR %d\n", i->ifa_index);
|
||||
if (i->ifa_family != AF_INET)
|
||||
return;
|
||||
if (!a[IFA_ADDRESS] || RTA_PAYLOAD(a[IFA_ADDRESS]) != 4 ||
|
||||
!a[IFA_LOCAL] || RTA_PAYLOAD(a[IFA_LOCAL]) != 4 ||
|
||||
(a[IFA_BROADCAST] && RTA_PAYLOAD(a[IFA_BROADCAST]) != 4))
|
||||
{
|
||||
log(L_ERR "nl_parse_addr: Malformed message received");
|
||||
return;
|
||||
}
|
||||
if (i->ifa_flags & IFA_F_SECONDARY)
|
||||
{
|
||||
DBG("KRT: Received address message for secondary address which is not supported.\n"); /* FIXME */
|
||||
return;
|
||||
}
|
||||
|
||||
ifi = if_find_by_index(i->ifa_index);
|
||||
if (!ifi)
|
||||
{
|
||||
log(L_ERR "KRT: Received address message for unknown interface %d\n", i->ifa_index);
|
||||
return;
|
||||
}
|
||||
memcpy(&f, ifi, sizeof(f));
|
||||
|
||||
if (i->ifa_prefixlen > 32 || i->ifa_prefixlen == 31 ||
|
||||
(f.flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
|
||||
{
|
||||
log(L_ERR "KRT: Invalid prefix length for interface %s: %d\n", f.name, i->ifa_prefixlen);
|
||||
new = 0;
|
||||
}
|
||||
|
||||
f.ip = f.brd = f.opposite = IPA_NONE;
|
||||
if (!new)
|
||||
{
|
||||
DBG("KRT: IF%d IP address deleted\n");
|
||||
f.pxlen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&f.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(f.ip));
|
||||
f.ip = ipa_ntoh(f.ip);
|
||||
f.pxlen = i->ifa_prefixlen;
|
||||
if (f.flags & IF_UNNUMBERED)
|
||||
{
|
||||
memcpy(&f.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(f.opposite));
|
||||
f.opposite = f.brd = ipa_ntoh(f.opposite);
|
||||
}
|
||||
else if ((f.flags & IF_BROADCAST) && a[IFA_BROADCAST])
|
||||
{
|
||||
memcpy(&f.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(f.brd));
|
||||
f.brd = ipa_ntoh(f.brd);
|
||||
}
|
||||
/* else a NBMA link */
|
||||
f.prefix = ipa_and(f.ip, ipa_mkmask(f.pxlen));
|
||||
DBG("KRT: IF%d IP address set to %I, net %I/%d, brd %I, opp %I\n", f.index, f.ip, f.prefix, f.pxlen, f.brd, f.opposite);
|
||||
}
|
||||
if_update(&f);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -219,10 +332,12 @@ nl_scan_ifaces(void)
|
|||
{
|
||||
struct nlmsghdr *h;
|
||||
|
||||
if_start_update();
|
||||
|
||||
nl_request_dump(RTM_GETLINK);
|
||||
while (h = nl_get_scan())
|
||||
if (h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)
|
||||
nl_parse_link(h);
|
||||
nl_parse_link(h, 1);
|
||||
else
|
||||
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
|
||||
|
||||
|
@ -233,7 +348,7 @@ nl_scan_ifaces(void)
|
|||
else
|
||||
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
|
||||
|
||||
bug("NIIDW");
|
||||
if_end_update();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue