summaryrefslogtreecommitdiff
path: root/ldpd/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldpd/interface.c')
-rw-r--r--ldpd/interface.c128
1 files changed, 79 insertions, 49 deletions
diff --git a/ldpd/interface.c b/ldpd/interface.c
index ff4c8f169c..b6472fe5e8 100644
--- a/ldpd/interface.c
+++ b/ldpd/interface.c
@@ -18,22 +18,20 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <string.h>
+#include <zebra.h>
#include "ldpd.h"
#include "ldpe.h"
#include "log.h"
+#include "sockopt.h"
+
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_hello_timer(int, short, void *);
+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 *);
static int if_join_ipv4_group(struct iface *, struct in_addr *);
@@ -50,20 +48,9 @@ if_new(struct kif *kif)
fatal("if_new: calloc");
strlcpy(iface->name, kif->ifname, sizeof(iface->name));
-
- /* get type */
- if (kif->flags & IFF_POINTOPOINT)
- iface->type = IF_TYPE_POINTOPOINT;
- if (kif->flags & IFF_BROADCAST &&
- kif->flags & IFF_MULTICAST)
- iface->type = IF_TYPE_BROADCAST;
-
- /* get index and flags */
LIST_INIT(&iface->addr_list);
- iface->ifindex = kif->ifindex;
- iface->flags = kif->flags;
- iface->linkstate = kif->link_state;
- iface->if_type = kif->if_type;
+ if (kif->ifindex)
+ if_update_info(iface, kif);
/* ipv4 */
iface->ipv4.af = AF_INET;
@@ -112,6 +99,33 @@ if_exit(struct iface *iface)
}
}
+struct iface *
+if_lookup_name(struct ldpd_conf *xconf, const char *ifname)
+{
+ struct iface *iface;
+
+ LIST_FOREACH(iface, &xconf->iface_list, entry)
+ if (strcmp(iface->name, ifname) == 0)
+ return (iface);
+
+ return (NULL);
+}
+
+void
+if_update_info(struct iface *iface, struct kif *kif)
+{
+ /* get type */
+ if (kif->flags & IFF_POINTOPOINT)
+ iface->type = IF_TYPE_POINTOPOINT;
+ if (kif->flags & IFF_BROADCAST &&
+ kif->flags & IFF_MULTICAST)
+ iface->type = IF_TYPE_BROADCAST;
+
+ /* get index and flags */
+ iface->ifindex = kif->ifindex;
+ iface->flags = kif->flags;
+}
+
struct iface_af *
iface_af_get(struct iface *iface, int af)
{
@@ -258,7 +272,6 @@ if_start(struct iface *iface, int af)
send_hello(HELLO_LINK, ia, NULL);
- evtimer_set(&ia->hello_timer, if_hello_timer, ia);
if_start_hello_timer(ia);
return (0);
}
@@ -328,7 +341,7 @@ if_update_af(struct iface_af *ia, int link_ok)
else
socket_ok = 0;
- if (leconf->rtr_id.s_addr != INADDR_ANY)
+ if (ldp_rtr_id_get(leconf) != INADDR_ANY)
rtr_id_ok = 1;
else
rtr_id_ok = 0;
@@ -354,8 +367,7 @@ if_update(struct iface *iface, int af)
{
int link_ok;
- link_ok = (iface->flags & IFF_UP) &&
- LINK_STATE_IS_UP(iface->linkstate);
+ link_ok = (iface->flags & IFF_UP) && (iface->flags & IFF_RUNNING);
if (af == AF_INET || af == AF_UNSPEC)
if_update_af(&iface->ipv4, link_ok);
@@ -372,34 +384,56 @@ if_update_all(int af)
if_update(iface, af);
}
+uint16_t
+if_get_hello_holdtime(struct iface_af *ia)
+{
+ if (ia->hello_holdtime != 0)
+ return (ia->hello_holdtime);
+
+ if ((ldp_af_conf_get(leconf, ia->af))->lhello_holdtime != 0)
+ return ((ldp_af_conf_get(leconf, ia->af))->lhello_holdtime);
+
+ return (leconf->lhello_holdtime);
+}
+
+uint16_t
+if_get_hello_interval(struct iface_af *ia)
+{
+ if (ia->hello_interval != 0)
+ return (ia->hello_interval);
+
+ if ((ldp_af_conf_get(leconf, ia->af))->lhello_interval != 0)
+ return ((ldp_af_conf_get(leconf, ia->af))->lhello_interval);
+
+ return (leconf->lhello_interval);
+}
+
/* timers */
/* ARGSUSED */
-static void
-if_hello_timer(int fd, short event, void *arg)
+static int
+if_hello_timer(struct thread *thread)
{
- struct iface_af *ia = arg;
+ struct iface_af *ia = THREAD_ARG(thread);
+ ia->hello_timer = NULL;
send_hello(HELLO_LINK, ia, NULL);
if_start_hello_timer(ia);
+
+ return (0);
}
static void
if_start_hello_timer(struct iface_af *ia)
{
- struct timeval tv;
-
- timerclear(&tv);
- tv.tv_sec = ia->hello_interval;
- if (evtimer_add(&ia->hello_timer, &tv) == -1)
- fatal(__func__);
+ THREAD_TIMER_OFF(ia->hello_timer);
+ ia->hello_timer = thread_add_timer(master, if_hello_timer, ia,
+ if_get_hello_interval(ia));
}
static void
if_stop_hello_timer(struct iface_af *ia)
{
- if (evtimer_pending(&ia->hello_timer, NULL) &&
- evtimer_del(&ia->hello_timer) == -1)
- fatal(__func__);
+ THREAD_TIMER_OFF(ia->hello_timer);
}
struct ctl_iface *
@@ -414,11 +448,9 @@ if_to_ctl(struct iface_af *ia)
ictl.ifindex = ia->iface->ifindex;
ictl.state = ia->state;
ictl.flags = ia->iface->flags;
- ictl.linkstate = ia->iface->linkstate;
ictl.type = ia->iface->type;
- ictl.if_type = ia->iface->if_type;
- ictl.hello_holdtime = ia->hello_holdtime;
- ictl.hello_interval = ia->hello_interval;
+ ictl.hello_holdtime = if_get_hello_holdtime(ia);
+ ictl.hello_interval = if_get_hello_interval(ia);
gettimeofday(&now, NULL);
if (ia->state != IF_STA_DOWN &&
@@ -450,16 +482,15 @@ if_get_ipv4_addr(struct iface *iface)
static int
if_join_ipv4_group(struct iface *iface, struct in_addr *addr)
{
- struct ip_mreq mreq;
+ struct in_addr if_addr;
log_debug("%s: interface %s addr %s", __func__, iface->name,
inet_ntoa(*addr));
- mreq.imr_multiaddr = *addr;
- mreq.imr_interface.s_addr = if_get_ipv4_addr(iface);
+ if_addr.s_addr = if_get_ipv4_addr(iface);
- if (setsockopt(global.ipv4.ldp_disc_socket, IPPROTO_IP,
- IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) < 0) {
+ if (setsockopt_ipv4_multicast(global.ipv4.ldp_disc_socket,
+ IP_ADD_MEMBERSHIP, if_addr, addr->s_addr, iface->ifindex) < 0) {
log_warn("%s: error IP_ADD_MEMBERSHIP, interface %s address %s",
__func__, iface->name, inet_ntoa(*addr));
return (-1);
@@ -470,16 +501,15 @@ if_join_ipv4_group(struct iface *iface, struct in_addr *addr)
static int
if_leave_ipv4_group(struct iface *iface, struct in_addr *addr)
{
- struct ip_mreq mreq;
+ struct in_addr if_addr;
log_debug("%s: interface %s addr %s", __func__, iface->name,
inet_ntoa(*addr));
- mreq.imr_multiaddr = *addr;
- mreq.imr_interface.s_addr = if_get_ipv4_addr(iface);
+ if_addr.s_addr = if_get_ipv4_addr(iface);
- if (setsockopt(global.ipv4.ldp_disc_socket, IPPROTO_IP,
- IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) < 0) {
+ if (setsockopt_ipv4_multicast(global.ipv4.ldp_disc_socket,
+ IP_DROP_MEMBERSHIP, if_addr, addr->s_addr, iface->ifindex) < 0) {
log_warn("%s: error IP_DROP_MEMBERSHIP, interface %s "
"address %s", __func__, iface->name, inet_ntoa(*addr));
return (-1);