Implements link state detection.
Also changes some symbol names (IFF_ADMIN_DOWN -> IFF_SHUTDOWN, IFF_LINK_UP -> IFF_ADMIN_UP).
This commit is contained in:
parent
5cdf264f93
commit
f25cb0ef9f
5 changed files with 38 additions and 18 deletions
26
nest/iface.c
26
nest/iface.c
|
@ -67,13 +67,13 @@ if_dump(struct iface *i)
|
||||||
struct ifa *a;
|
struct ifa *a;
|
||||||
|
|
||||||
debug("IF%d: %s", i->index, i->name);
|
debug("IF%d: %s", i->index, i->name);
|
||||||
if (i->flags & IF_ADMIN_DOWN)
|
if (i->flags & IF_SHUTDOWN)
|
||||||
debug(" ADMIN-DOWN");
|
debug(" SHUTDOWN");
|
||||||
if (i->flags & IF_UP)
|
if (i->flags & IF_UP)
|
||||||
debug(" UP");
|
debug(" UP");
|
||||||
else
|
else
|
||||||
debug(" DOWN");
|
debug(" DOWN");
|
||||||
if (i->flags & IF_LINK_UP)
|
if (i->flags & IF_ADMIN_UP)
|
||||||
debug(" LINK-UP");
|
debug(" LINK-UP");
|
||||||
if (i->flags & IF_MULTIACCESS)
|
if (i->flags & IF_MULTIACCESS)
|
||||||
debug(" MA");
|
debug(" MA");
|
||||||
|
@ -117,12 +117,14 @@ if_what_changed(struct iface *i, struct iface *j)
|
||||||
{
|
{
|
||||||
unsigned c;
|
unsigned c;
|
||||||
|
|
||||||
if (((i->flags ^ j->flags) & ~(IF_UP | IF_ADMIN_DOWN | IF_UPDATED | IF_LINK_UP | IF_TMP_DOWN | IF_JUST_CREATED))
|
if (((i->flags ^ j->flags) & ~(IF_UP | IF_SHUTDOWN | IF_UPDATED | IF_ADMIN_UP | IF_TMP_DOWN | IF_JUST_CREATED))
|
||||||
|| i->index != j->index)
|
|| i->index != j->index)
|
||||||
return IF_CHANGE_TOO_MUCH;
|
return IF_CHANGE_TOO_MUCH;
|
||||||
c = 0;
|
c = 0;
|
||||||
if ((i->flags ^ j->flags) & IF_UP)
|
if ((i->flags ^ j->flags) & IF_UP)
|
||||||
c |= (i->flags & IF_UP) ? IF_CHANGE_DOWN : IF_CHANGE_UP;
|
c |= (i->flags & IF_UP) ? IF_CHANGE_DOWN : IF_CHANGE_UP;
|
||||||
|
if ((i->flags ^ j->flags) & IF_LINK_UP)
|
||||||
|
c |= IF_CHANGE_LINK;
|
||||||
if (i->mtu != j->mtu)
|
if (i->mtu != j->mtu)
|
||||||
c |= IF_CHANGE_MTU;
|
c |= IF_CHANGE_MTU;
|
||||||
return c;
|
return c;
|
||||||
|
@ -169,6 +171,7 @@ if_send_notify(struct proto *p, unsigned c, struct iface *i)
|
||||||
(c & IF_CHANGE_UP) ? "goes up" :
|
(c & IF_CHANGE_UP) ? "goes up" :
|
||||||
(c & IF_CHANGE_DOWN) ? "goes down" :
|
(c & IF_CHANGE_DOWN) ? "goes down" :
|
||||||
(c & IF_CHANGE_MTU) ? "changes MTU" :
|
(c & IF_CHANGE_MTU) ? "changes MTU" :
|
||||||
|
(c & IF_CHANGE_LINK) ? "changes link" :
|
||||||
(c & IF_CHANGE_CREATE) ? "created" :
|
(c & IF_CHANGE_CREATE) ? "created" :
|
||||||
"sends unknown event");
|
"sends unknown event");
|
||||||
p->if_notify(p, c, i);
|
p->if_notify(p, c, i);
|
||||||
|
@ -217,8 +220,8 @@ if_notify_change(unsigned c, struct iface *i)
|
||||||
static unsigned
|
static unsigned
|
||||||
if_recalc_flags(struct iface *i, unsigned flags)
|
if_recalc_flags(struct iface *i, unsigned flags)
|
||||||
{
|
{
|
||||||
if ((flags & (IF_ADMIN_DOWN | IF_TMP_DOWN)) ||
|
if ((flags & (IF_SHUTDOWN | IF_TMP_DOWN)) ||
|
||||||
!(flags & IF_LINK_UP) ||
|
!(flags & IF_ADMIN_UP) ||
|
||||||
!i->addr)
|
!i->addr)
|
||||||
flags &= ~IF_UP;
|
flags &= ~IF_UP;
|
||||||
else
|
else
|
||||||
|
@ -325,7 +328,7 @@ if_end_update(void)
|
||||||
WALK_LIST(i, iface_list)
|
WALK_LIST(i, iface_list)
|
||||||
{
|
{
|
||||||
if (!(i->flags & IF_UPDATED))
|
if (!(i->flags & IF_UPDATED))
|
||||||
if_change_flags(i, (i->flags & ~IF_LINK_UP) | IF_ADMIN_DOWN);
|
if_change_flags(i, (i->flags & ~IF_ADMIN_UP) | IF_SHUTDOWN);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WALK_LIST_DELSAFE(a, b, i->addrs)
|
WALK_LIST_DELSAFE(a, b, i->addrs)
|
||||||
|
@ -535,8 +538,8 @@ auto_router_id(void)
|
||||||
|
|
||||||
j = NULL;
|
j = NULL;
|
||||||
WALK_LIST(i, iface_list)
|
WALK_LIST(i, iface_list)
|
||||||
if ((i->flags & IF_LINK_UP) &&
|
if ((i->flags & IF_ADMIN_UP) &&
|
||||||
!(i->flags & (IF_IGNORE | IF_ADMIN_DOWN)) &&
|
!(i->flags & (IF_IGNORE | IF_SHUTDOWN)) &&
|
||||||
i->addr &&
|
i->addr &&
|
||||||
!(i->addr->flags & IA_UNNUMBERED) &&
|
!(i->addr->flags & IA_UNNUMBERED) &&
|
||||||
(!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip)))
|
(!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip)))
|
||||||
|
@ -694,6 +697,9 @@ if_show(void)
|
||||||
|
|
||||||
WALK_LIST(i, iface_list)
|
WALK_LIST(i, iface_list)
|
||||||
{
|
{
|
||||||
|
if (i->flags & IF_SHUTDOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
cli_msg(-1001, "%s %s (index=%d)", i->name, (i->flags & IF_UP) ? "up" : "DOWN", i->index);
|
cli_msg(-1001, "%s %s (index=%d)", i->name, (i->flags & IF_UP) ? "up" : "DOWN", i->index);
|
||||||
if (!(i->flags & IF_MULTIACCESS))
|
if (!(i->flags & IF_MULTIACCESS))
|
||||||
type = "PtP";
|
type = "PtP";
|
||||||
|
@ -703,7 +709,7 @@ if_show(void)
|
||||||
type,
|
type,
|
||||||
(i->flags & IF_BROADCAST) ? " Broadcast" : "",
|
(i->flags & IF_BROADCAST) ? " Broadcast" : "",
|
||||||
(i->flags & IF_MULTICAST) ? " Multicast" : "",
|
(i->flags & IF_MULTICAST) ? " Multicast" : "",
|
||||||
(i->flags & IF_ADMIN_DOWN) ? "Down" : "Up",
|
(i->flags & IF_ADMIN_UP) ? "Up" : "Down",
|
||||||
(i->flags & IF_LINK_UP) ? "Up" : "Down",
|
(i->flags & IF_LINK_UP) ? "Up" : "Down",
|
||||||
(i->flags & IF_LOOPBACK) ? " Loopback" : "",
|
(i->flags & IF_LOOPBACK) ? " Loopback" : "",
|
||||||
(i->flags & IF_IGNORE) ? " Ignored" : "",
|
(i->flags & IF_IGNORE) ? " Ignored" : "",
|
||||||
|
|
|
@ -39,14 +39,15 @@ struct iface {
|
||||||
list neighbors; /* All neighbors on this interface */
|
list neighbors; /* All neighbors on this interface */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IF_UP 1 /* IF_LINK_UP and IP address known */
|
#define IF_UP 1 /* IF_ADMIN_UP and IP address known */
|
||||||
#define IF_MULTIACCESS 2
|
#define IF_MULTIACCESS 2
|
||||||
#define IF_BROADCAST 4
|
#define IF_BROADCAST 4
|
||||||
#define IF_MULTICAST 8
|
#define IF_MULTICAST 8
|
||||||
#define IF_ADMIN_DOWN 0x10
|
#define IF_SHUTDOWN 0x10 /* Interface disappeared */
|
||||||
#define IF_LOOPBACK 0x20
|
#define IF_LOOPBACK 0x20
|
||||||
#define IF_IGNORE 0x40 /* Not to be used by routing protocols (loopbacks etc.) */
|
#define IF_IGNORE 0x40 /* Not to be used by routing protocols (loopbacks etc.) */
|
||||||
#define IF_LINK_UP 0x80
|
#define IF_ADMIN_UP 0x80 /* Administrative up (e.q. IFF_UP in Linux) */
|
||||||
|
#define IF_LINK_UP 0x100 /* Link available (e.q. IFF_LOWER_UP in Linux) */
|
||||||
|
|
||||||
#define IA_PRIMARY 0x10000 /* This address is primary */
|
#define IA_PRIMARY 0x10000 /* This address is primary */
|
||||||
#define IA_SECONDARY 0x20000 /* This address has been reported as secondary by the kernel */
|
#define IA_SECONDARY 0x20000 /* This address has been reported as secondary by the kernel */
|
||||||
|
@ -63,6 +64,7 @@ struct iface {
|
||||||
#define IF_CHANGE_DOWN 2
|
#define IF_CHANGE_DOWN 2
|
||||||
#define IF_CHANGE_MTU 4
|
#define IF_CHANGE_MTU 4
|
||||||
#define IF_CHANGE_CREATE 8 /* Seen this interface for the first time */
|
#define IF_CHANGE_CREATE 8 /* Seen this interface for the first time */
|
||||||
|
#define IF_CHANGE_LINK 0x10
|
||||||
#define IF_CHANGE_TOO_MUCH 0x40000000 /* Used internally */
|
#define IF_CHANGE_TOO_MUCH 0x40000000 /* Used internally */
|
||||||
|
|
||||||
void if_init(void);
|
void if_init(void);
|
||||||
|
|
|
@ -456,7 +456,9 @@ krt_read_ifinfo(struct ks_msg *msg)
|
||||||
f.flags = 0;
|
f.flags = 0;
|
||||||
|
|
||||||
if (fl & IFF_UP)
|
if (fl & IFF_UP)
|
||||||
f.flags |= IF_LINK_UP;
|
f.flags |= IF_ADMIN_UP;
|
||||||
|
if (ifm->ifm_data.ifi_link_state != LINK_STATE_DOWN)
|
||||||
|
f.flags |= IF_LINK_UP; /* up or unknown */
|
||||||
if (fl & IFF_LOOPBACK) /* Loopback */
|
if (fl & IFF_LOOPBACK) /* Loopback */
|
||||||
f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
|
f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
|
||||||
else if (fl & IFF_POINTOPOINT) /* PtP */
|
else if (fl & IFF_POINTOPOINT) /* PtP */
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <net/if.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
|
#include <linux/if.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
|
@ -34,6 +34,10 @@
|
||||||
#define MSG_TRUNC 0x20
|
#define MSG_TRUNC 0x20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef IFF_LOWER_UP
|
||||||
|
#define IFF_LOWER_UP 0x10000
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Synchronous Netlink interface
|
* Synchronous Netlink interface
|
||||||
*/
|
*/
|
||||||
|
@ -281,6 +285,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
||||||
u32 mtu;
|
u32 mtu;
|
||||||
unsigned int fl;
|
unsigned int fl;
|
||||||
|
|
||||||
|
debug("nl_parse_link %d\n", new);
|
||||||
|
|
||||||
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFLA_RTA(i), a, sizeof(a)))
|
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFLA_RTA(i), a, sizeof(a)))
|
||||||
return;
|
return;
|
||||||
if (!a[IFLA_IFNAME] || RTA_PAYLOAD(a[IFLA_IFNAME]) < 2 ||
|
if (!a[IFLA_IFNAME] || RTA_PAYLOAD(a[IFLA_IFNAME]) < 2 ||
|
||||||
|
@ -293,6 +299,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
||||||
name = RTA_DATA(a[IFLA_IFNAME]);
|
name = RTA_DATA(a[IFLA_IFNAME]);
|
||||||
memcpy(&mtu, RTA_DATA(a[IFLA_MTU]), sizeof(u32));
|
memcpy(&mtu, RTA_DATA(a[IFLA_MTU]), sizeof(u32));
|
||||||
|
|
||||||
|
debug("nl_parse_link name %s index %d flags %x\n", name, i->ifi_index, i->ifi_flags);
|
||||||
|
|
||||||
ifi = if_find_by_index(i->ifi_index);
|
ifi = if_find_by_index(i->ifi_index);
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
|
@ -300,7 +308,7 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
||||||
if (ifi && !scan)
|
if (ifi && !scan)
|
||||||
{
|
{
|
||||||
memcpy(&f, ifi, sizeof(struct iface));
|
memcpy(&f, ifi, sizeof(struct iface));
|
||||||
f.flags |= IF_ADMIN_DOWN;
|
f.flags |= IF_SHUTDOWN;
|
||||||
if_update(&f);
|
if_update(&f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,6 +327,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
||||||
f.flags = 0;
|
f.flags = 0;
|
||||||
fl = i->ifi_flags;
|
fl = i->ifi_flags;
|
||||||
if (fl & IFF_UP)
|
if (fl & IFF_UP)
|
||||||
|
f.flags |= IF_ADMIN_UP;
|
||||||
|
if (fl & IFF_LOWER_UP)
|
||||||
f.flags |= IF_LINK_UP;
|
f.flags |= IF_LINK_UP;
|
||||||
if (fl & IFF_LOOPBACK) /* Loopback */
|
if (fl & IFF_LOOPBACK) /* Loopback */
|
||||||
f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
|
f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
|
||||||
|
|
|
@ -78,12 +78,12 @@ scan_ifs(struct ifreq *r, int cnt)
|
||||||
faulty:
|
faulty:
|
||||||
log(L_ERR "%s(%s): %m", err, i.name);
|
log(L_ERR "%s(%s): %m", err, i.name);
|
||||||
bad:
|
bad:
|
||||||
i.flags = (i.flags & ~IF_LINK_UP) | IF_ADMIN_DOWN;
|
i.flags = (i.flags & ~IF_ADMIN_UP) | IF_SHUTDOWN;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fl = r->ifr_flags;
|
fl = r->ifr_flags;
|
||||||
if (fl & IFF_UP)
|
if (fl & IFF_UP)
|
||||||
i.flags |= IF_LINK_UP;
|
i.flags |= IF_ADMIN_UP;
|
||||||
|
|
||||||
if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
|
if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
|
||||||
{ err = "SIOCGIFNETMASK"; goto faulty; }
|
{ err = "SIOCGIFNETMASK"; goto faulty; }
|
||||||
|
|
Loading…
Reference in a new issue