summaryrefslogtreecommitdiff
path: root/ldpd/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldpd/interface.c')
-rw-r--r--ldpd/interface.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/ldpd/interface.c b/ldpd/interface.c
index 8fea91b878..a064a58b2e 100644
--- a/ldpd/interface.c
+++ b/ldpd/interface.c
@@ -31,7 +31,7 @@ static struct if_addr *if_addr_new(struct kaddr *);
static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *);
static int if_start(struct iface *, int);
static int if_reset(struct iface *, int);
-static void if_update_af(struct iface_af *, int);
+static void if_update_af(struct iface_af *);
static int if_hello_timer(struct thread *);
static void if_start_hello_timer(struct iface_af *);
static void if_stop_hello_timer(struct iface_af *);
@@ -49,37 +49,48 @@ iface_compare(struct iface *a, struct iface *b)
}
struct iface *
-if_new(struct kif *kif)
+if_new(const char *name)
{
struct iface *iface;
if ((iface = calloc(1, sizeof(*iface))) == NULL)
fatal("if_new: calloc");
- strlcpy(iface->name, kif->ifname, sizeof(iface->name));
- LIST_INIT(&iface->addr_list);
- if (kif->ifindex)
- if_update_info(iface, kif);
+ strlcpy(iface->name, name, sizeof(iface->name));
/* ipv4 */
iface->ipv4.af = AF_INET;
iface->ipv4.iface = iface;
iface->ipv4.enabled = 0;
- iface->ipv4.state = IF_STA_DOWN;
- RB_INIT(&iface->ipv4.adj_tree);
/* ipv6 */
iface->ipv6.af = AF_INET6;
iface->ipv6.iface = iface;
iface->ipv6.enabled = 0;
- iface->ipv6.state = IF_STA_DOWN;
- RB_INIT(&iface->ipv6.adj_tree);
return (iface);
}
void
-if_exit(struct iface *iface)
+ldpe_if_init(struct iface *iface)
+{
+ log_debug("%s: interface %s", __func__, iface->name);
+
+ LIST_INIT(&iface->addr_list);
+
+ /* ipv4 */
+ iface->ipv4.iface = iface;
+ iface->ipv4.state = IF_STA_DOWN;
+ RB_INIT(&iface->ipv4.adj_tree);
+
+ /* ipv6 */
+ iface->ipv6.iface = iface;
+ iface->ipv6.state = IF_STA_DOWN;
+ RB_INIT(&iface->ipv6.adj_tree);
+}
+
+void
+ldpe_if_exit(struct iface *iface)
{
struct if_addr *if_addr;
@@ -128,7 +139,7 @@ if_update_info(struct iface *iface, struct kif *kif)
/* get index and flags */
iface->ifindex = kif->ifindex;
- iface->flags = kif->flags;
+ iface->operative = kif->operative;
}
struct iface_af *
@@ -198,7 +209,7 @@ if_addr_add(struct kaddr *ka)
}
}
- iface = if_lookup(leconf, ka->ifindex);
+ iface = if_lookup_name(leconf, ka->ifname);
if (iface) {
if (ka->af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&ka->addr.v6))
iface->linklocal = ka->addr.v6;
@@ -206,7 +217,7 @@ if_addr_add(struct kaddr *ka)
if (if_addr_lookup(&iface->addr_list, ka) == NULL) {
if_addr = if_addr_new(ka);
LIST_INSERT_HEAD(&iface->addr_list, if_addr, entry);
- if_update(iface, if_addr->af);
+ ldp_if_update(iface, if_addr->af);
}
}
}
@@ -218,7 +229,7 @@ if_addr_del(struct kaddr *ka)
struct if_addr *if_addr;
struct nbr *nbr;
- iface = if_lookup(leconf, ka->ifindex);
+ iface = if_lookup_name(leconf, ka->ifname);
if (iface) {
if (ka->af == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&iface->linklocal, &ka->addr.v6))
@@ -227,7 +238,7 @@ if_addr_del(struct kaddr *ka)
if_addr = if_addr_lookup(&iface->addr_list, ka);
if (if_addr) {
LIST_REMOVE(if_addr, entry);
- if_update(iface, if_addr->af);
+ ldp_if_update(iface, if_addr->af);
free(if_addr);
}
}
@@ -276,8 +287,9 @@ if_start(struct iface *iface, int af)
}
send_hello(HELLO_LINK, ia, NULL);
-
if_start_hello_timer(ia);
+ ia->state = IF_STA_ACTIVE;
+
return (0);
}
@@ -307,14 +319,16 @@ if_reset(struct iface *iface, int af)
if_leave_ipv6_group(iface, &global.mcast_addr_v6);
break;
default:
- fatalx("if_start: unknown af");
+ fatalx("if_reset: unknown af");
}
+ ia->state = IF_STA_DOWN;
+
return (0);
}
static void
-if_update_af(struct iface_af *ia, int link_ok)
+if_update_af(struct iface_af *ia)
{
int addr_ok = 0, socket_ok, rtr_id_ok;
struct if_addr *if_addr;
@@ -352,32 +366,27 @@ if_update_af(struct iface_af *ia, int link_ok)
rtr_id_ok = 0;
if (ia->state == IF_STA_DOWN) {
- if (!ia->enabled || !link_ok || !addr_ok || !socket_ok ||
- !rtr_id_ok)
+ if (!ia->enabled || !ia->iface->operative || !addr_ok ||
+ !socket_ok || !rtr_id_ok)
return;
- ia->state = IF_STA_ACTIVE;
if_start(ia->iface, ia->af);
} else if (ia->state == IF_STA_ACTIVE) {
- if (ia->enabled && link_ok && addr_ok && socket_ok && rtr_id_ok)
+ if (ia->enabled && ia->iface->operative && addr_ok &&
+ socket_ok && rtr_id_ok)
return;
- ia->state = IF_STA_DOWN;
if_reset(ia->iface, ia->af);
}
}
void
-if_update(struct iface *iface, int af)
+ldp_if_update(struct iface *iface, int af)
{
- int link_ok;
-
- link_ok = (iface->flags & IFF_UP) && (iface->flags & IFF_RUNNING);
-
if (af == AF_INET || af == AF_UNSPEC)
- if_update_af(&iface->ipv4, link_ok);
+ if_update_af(&iface->ipv4);
if (af == AF_INET6 || af == AF_UNSPEC)
- if_update_af(&iface->ipv6, link_ok);
+ if_update_af(&iface->ipv6);
}
void
@@ -386,7 +395,7 @@ if_update_all(int af)
struct iface *iface;
RB_FOREACH(iface, iface_head, &leconf->iface_tree)
- if_update(iface, af);
+ ldp_if_update(iface, af);
}
uint16_t
@@ -431,8 +440,9 @@ static void
if_start_hello_timer(struct iface_af *ia)
{
THREAD_TIMER_OFF(ia->hello_timer);
- ia->hello_timer = thread_add_timer(master, if_hello_timer, ia,
- if_get_hello_interval(ia));
+ ia->hello_timer = NULL;
+ thread_add_timer(master, if_hello_timer, ia, if_get_hello_interval(ia),
+ &ia->hello_timer);
}
static void
@@ -452,7 +462,6 @@ if_to_ctl(struct iface_af *ia)
memcpy(ictl.name, ia->iface->name, sizeof(ictl.name));
ictl.ifindex = ia->iface->ifindex;
ictl.state = ia->state;
- ictl.flags = ia->iface->flags;
ictl.type = ia->iface->type;
ictl.hello_holdtime = if_get_hello_holdtime(ia);
ictl.hello_interval = if_get_hello_interval(ia);