summaryrefslogtreecommitdiff
path: root/usr.sbin/ospf6d/kroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ospf6d/kroute.c')
-rw-r--r--usr.sbin/ospf6d/kroute.c251
1 files changed, 73 insertions, 178 deletions
diff --git a/usr.sbin/ospf6d/kroute.c b/usr.sbin/ospf6d/kroute.c
index 52f65f501ee..df80f157c1d 100644
--- a/usr.sbin/ospf6d/kroute.c
+++ b/usr.sbin/ospf6d/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.5 2007/10/17 20:54:41 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.6 2007/12/13 08:54:05 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -38,6 +38,7 @@
#include <unistd.h>
#include "ospf6d.h"
+#include "ospfe.h"
#include "log.h"
struct {
@@ -54,17 +55,10 @@ struct kroute_node {
struct kroute_node *next;
};
-struct kif_node {
- RB_ENTRY(kif_node) entry;
- TAILQ_HEAD(, kif_addr) addrs;
- struct kif k;
-};
-
void kr_redist_remove(struct kroute_node *, struct kroute_node *);
int kr_redist_eval(struct kroute *, struct rroute *);
void kr_redistribute(struct kroute_node *);
int kroute_compare(struct kroute_node *, struct kroute_node *);
-int kif_compare(struct kif_node *, struct kif_node *);
struct kroute_node *kroute_find(const struct in6_addr *, u_int8_t);
struct kroute_node *kroute_matchgw(struct kroute_node *,
@@ -73,12 +67,8 @@ int kroute_insert(struct kroute_node *);
int kroute_remove(struct kroute_node *);
void kroute_clear(void);
-struct kif_node *kif_find(u_short);
-struct kif_node *kif_insert(u_short);
-int kif_remove(struct kif_node *);
-void kif_clear(void);
-struct kif *kif_update(u_short, int, struct if_data *,
- struct sockaddr_dl *);
+struct iface *kif_update(u_short, int, struct if_data *,
+ struct sockaddr_dl *);
int kif_validate(u_short);
struct kroute_node *kroute_match(struct in6_addr *);
@@ -93,27 +83,11 @@ void if_announce(void *);
int send_rtmsg(int, int, struct kroute *);
int dispatch_rtmsg(void);
int fetchtable(void);
-int fetchifs(u_short);
RB_HEAD(kroute_tree, kroute_node) krt;
RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare)
-RB_HEAD(kif_tree, kif_node) kit;
-RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare)
-RB_GENERATE(kif_tree, kif_node, entry, kif_compare)
-
-int
-kif_init(void)
-{
- RB_INIT(&kit);
-
- if (fetchifs(0) == -1)
- return (-1);
-
- return (0);
-}
-
int
kr_init(int fs)
{
@@ -271,7 +245,6 @@ kr_shutdown(void)
{
kr_fib_decouple();
kroute_clear();
- kif_clear();
}
void
@@ -362,20 +335,6 @@ kr_show_route(struct imsg *imsg)
}
void
-kr_ifinfo(char *ifname, pid_t pid)
-{
- struct kif_node *kif;
-
- RB_FOREACH(kif, kif_tree, &kit)
- if (ifname == NULL || !strcmp(ifname, kif->k.ifname)) {
- main_imsg_compose_ospfe(IMSG_CTL_IFINFO,
- pid, &kif->k, sizeof(kif->k));
- }
-
- main_imsg_compose_ospfe(IMSG_CTL_END, pid, NULL, 0);
-}
-
-void
kr_redist_remove(struct kroute_node *kh, struct kroute_node *kn)
{
struct rroute rr;
@@ -530,12 +489,6 @@ kroute_compare(struct kroute_node *a, struct kroute_node *b)
return (0);
}
-int
-kif_compare(struct kif_node *a, struct kif_node *b)
-{
- return (b->k.ifindex - a->k.ifindex);
-}
-
/* tree management */
struct kroute_node *
kroute_find(const struct in6_addr *prefix, u_int8_t prefixlen)
@@ -648,118 +601,45 @@ kroute_clear(void)
kroute_remove(kr);
}
-struct kif_node *
-kif_find(u_short ifindex)
-{
- struct kif_node s;
-
- bzero(&s, sizeof(s));
- s.k.ifindex = ifindex;
-
- return (RB_FIND(kif_tree, &kit, &s));
-}
-
-struct kif *
-kif_findname(char *ifname, struct kif_addr **kap)
-{
- struct kif_node *kif;
- struct kif_addr *ka;
-
- RB_FOREACH(kif, kif_tree, &kit)
- if (!strcmp(ifname, kif->k.ifname)) {
- ka = TAILQ_FIRST(&kif->addrs);
- if (kap != NULL)
- *kap = ka;
- return (&kif->k);
- }
-
- return (NULL);
-}
-
-struct kif_node *
-kif_insert(u_short ifindex)
-{
- struct kif_node *kif;
-
- if ((kif = calloc(1, sizeof(struct kif_node))) == NULL)
- return (NULL);
-
- kif->k.ifindex = ifindex;
- TAILQ_INIT(&kif->addrs);
-
- if (RB_INSERT(kif_tree, &kit, kif) != NULL)
- fatalx("kif_insert: RB_INSERT");
-
- return (kif);
-}
-
-int
-kif_remove(struct kif_node *kif)
-{
- struct kif_addr *ka;
-
- if (RB_REMOVE(kif_tree, &kit, kif) == NULL) {
- log_warnx("RB_REMOVE(kif_tree, &kit, kif)");
- return (-1);
- }
-
- while ((ka = TAILQ_FIRST(&kif->addrs)) != NULL) {
- TAILQ_REMOVE(&kif->addrs, ka, entry);
- free(ka);
- }
- free(kif);
- return (0);
-}
-
-void
-kif_clear(void)
-{
- struct kif_node *kif;
-
- while ((kif = RB_MIN(kif_tree, &kit)) != NULL)
- kif_remove(kif);
-}
-
-struct kif *
+struct iface *
kif_update(u_short ifindex, int flags, struct if_data *ifd,
struct sockaddr_dl *sdl)
{
- struct kif_node *kif;
+ struct iface *iface;
+ char ifname[IF_NAMESIZE];
+
+ if ((iface = if_find(ifindex)) == NULL) {
+ if (sdl && sdl->sdl_family == AF_LINK) {
+ bzero(ifname, sizeof(ifname));
+ if (sdl->sdl_nlen >= sizeof(ifname))
+ memcpy(ifname, sdl->sdl_data,
+ sizeof(ifname) - 1);
+ else if (sdl->sdl_nlen > 0)
+ memcpy(ifname, sdl->sdl_data, sdl->sdl_nlen);
+ }
- if ((kif = kif_find(ifindex)) == NULL)
- if ((kif = kif_insert(ifindex)) == NULL)
+ if ((iface = if_new(ifindex, ifname)) == NULL)
return (NULL);
-
- kif->k.flags = flags;
- kif->k.link_state = ifd->ifi_link_state;
- kif->k.media_type = ifd->ifi_type;
- kif->k.baudrate = ifd->ifi_baudrate;
- kif->k.mtu = ifd->ifi_mtu;
-
- if (sdl && sdl->sdl_family == AF_LINK) {
- if (sdl->sdl_nlen >= sizeof(kif->k.ifname))
- memcpy(kif->k.ifname, sdl->sdl_data,
- sizeof(kif->k.ifname) - 1);
- else if (sdl->sdl_nlen > 0)
- memcpy(kif->k.ifname, sdl->sdl_data,
- sdl->sdl_nlen);
- /* string already terminated via calloc() */
+ iface->cflags |= F_IFACE_AVAIL;
}
- return (&kif->k);
+ if_update(iface, ifd->ifi_mtu, flags, ifd->ifi_type,
+ ifd->ifi_link_state, ifd->ifi_baudrate);
+
+ return (iface);
}
int
kif_validate(u_short ifindex)
{
- struct kif_node *kif;
+ struct iface *iface;
- if ((kif = kif_find(ifindex)) == NULL) {
+ if ((iface = if_find(ifindex)) == NULL) {
log_warnx("interface with index %u not found", ifindex);
return (1);
}
- return (kif->k.nh_reachable);
+ return (iface->nh_reachable);
}
struct kroute_node *
@@ -907,26 +787,28 @@ void
if_change(u_short ifindex, int flags, struct if_data *ifd)
{
struct kroute_node *kr, *tkr;
- struct kif *kif;
+ struct iface *iface;
u_int8_t reachable;
- if ((kif = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
+ if ((iface = kif_update(ifindex, flags, ifd, NULL)) == NULL) {
log_warn("if_change: kif_update(%u)", ifindex);
return;
}
- reachable = (kif->flags & IFF_UP) &&
- (LINK_STATE_IS_UP(kif->link_state) ||
- (kif->link_state == LINK_STATE_UNKNOWN &&
- kif->media_type != IFT_CARP));
+ reachable = (iface->flags & IFF_UP) &&
+ (LINK_STATE_IS_UP(iface->linkstate) ||
+ (iface->linkstate == LINK_STATE_UNKNOWN &&
+ iface->media_type != IFT_CARP));
- if (reachable == kif->nh_reachable)
+ if (reachable == iface->nh_reachable)
return; /* nothing changed wrt nexthop validity */
- kif->nh_reachable = reachable;
+ iface->nh_reachable = reachable;
/* notify ospfe about interface link state */
- main_imsg_compose_ospfe(IMSG_IFINFO, 0, kif, sizeof(struct kif));
+ if (iface->cflags & F_IFACE_CONFIGURED)
+ main_imsg_compose_ospfe(IMSG_IFINFO, 0, iface,
+ sizeof(struct iface));
/* update redistribute list */
RB_FOREACH(kr, kroute_tree, &krt) {
@@ -947,56 +829,69 @@ void
if_newaddr(u_short ifindex, struct sockaddr_in6 *ifa, struct sockaddr_in6 *mask,
struct sockaddr_in6 *brd)
{
- struct kif_node *kif;
- struct kif_addr *ka;
+ struct iface *iface;
+ struct iface_addr *ia;
if (ifa == NULL || ifa->sin6_family != AF_INET6)
return;
- if ((kif = kif_find(ifindex)) == NULL) {
+ if ((iface = if_find(ifindex)) == NULL) {
log_warnx("if_newaddr: corresponding if %i not found", ifindex);
return;
}
- if ((ka = calloc(1, sizeof(struct kif_addr))) == NULL)
- fatal("if_newaddr");
- ka->addr = ifa->sin6_addr;
-
/* XXX thanks, KAME, for this ugliness... adopted from route/show.c */
- if (IN6_IS_ADDR_LINKLOCAL(&ka->addr) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&ka->addr)) {
- ka->addr.s6_addr[2] = 0;
- ka->addr.s6_addr[3] = 0;
+ if (IN6_IS_ADDR_LINKLOCAL(&ifa->sin6_addr) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(&ifa->sin6_addr)) {
+ ifa->sin6_addr.s6_addr[2] = 0;
+ ifa->sin6_addr.s6_addr[3] = 0;
}
+ if (IN6_IS_ADDR_LINKLOCAL(&ifa->sin6_addr))
+ iface->addr = ifa->sin6_addr;
+
+ if ((ia = calloc(1, sizeof(struct iface_addr))) == NULL)
+ fatal("if_newaddr");
+
+ ia->addr = ifa->sin6_addr;
+
if (mask)
- ka->mask = mask->sin6_addr;
+ ia->prefixlen = 64; // XXX mask2prefixlen(&mask->sin6_addr);
else
- bzero(&ka->mask, sizeof(ka->mask));
+ ia->prefixlen = 0;
+#if 0 /* XXX fix me */
if (brd)
ka->dstbrd = brd->sin6_addr;
else
bzero(&ka->dstbrd, sizeof(ka->dstbrd));
+#endif
log_debug("if_newaddr: ifindex %u, addr %s", ifindex,
- log_in6addr(&ka->addr));
- TAILQ_INSERT_TAIL(&kif->addrs, ka, entry);
+ log_in6addr(&ia->addr));
+ TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry);
}
void
if_announce(void *msg)
{
struct if_announcemsghdr *ifan;
- struct kif_node *kif;
+ struct iface *iface;
ifan = msg;
switch (ifan->ifan_what) {
case IFAN_ARRIVAL:
- kif = kif_insert(ifan->ifan_index);
- strlcpy(kif->k.ifname, ifan->ifan_name, sizeof(kif->k.ifname));
+ if ((iface = if_new(ifan->ifan_index, ifan->ifan_name)) == NULL)
+ fatal("if_new failed");
+ iface->cflags |= F_IFACE_AVAIL;
break;
case IFAN_DEPARTURE:
- kif = kif_find(ifan->ifan_index);
- kif_remove(kif);
+ iface = if_find(ifan->ifan_index);
+ if (iface->cflags & F_IFACE_CONFIGURED) {
+ main_imsg_compose_rde(IMSG_IFDELETE, 0,
+ &iface->ifindex, sizeof(iface->ifindex));
+ main_imsg_compose_ospfe(IMSG_IFDELETE, 0,
+ &iface->ifindex, sizeof(iface->ifindex));
+ }
+ if_del(iface);
break;
}
}
@@ -1234,7 +1129,7 @@ fetchifs(u_short ifindex)
struct rt_msghdr *rtm;
struct if_msghdr ifm;
struct ifa_msghdr *ifam;
- struct kif *kif = NULL;
+ struct iface *iface;
struct sockaddr *sa, *rti_info[RTAX_MAX];
mib[0] = CTL_NET;
@@ -1269,12 +1164,12 @@ fetchifs(u_short ifindex)
sa = (struct sockaddr *)(next + sizeof(ifm));
get_rtaddrs(ifm.ifm_addrs, sa, rti_info);
- if ((kif = kif_update(ifm.ifm_index,
+ if ((iface = kif_update(ifm.ifm_index,
ifm.ifm_flags, &ifm.ifm_data,
(struct sockaddr_dl *)rti_info[RTAX_IFP])) == NULL)
fatal("fetchifs");
- kif->nh_reachable = (kif->flags & IFF_UP) &&
+ iface->nh_reachable = (iface->flags & IFF_UP) &&
(LINK_STATE_IS_UP(ifm.ifm_data.ifi_link_state) ||
(ifm.ifm_data.ifi_link_state ==
LINK_STATE_UNKNOWN &&