summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-12-22 19:32:37 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-12-22 19:32:37 +0000
commitf316ce14f69eb4c0b9394d5428eba322989b4e60 (patch)
tree701ea319959c80652d9810fd636d533366d50884
parent99ee7ca0066d75aec98ffdf7976e3002288e29fa (diff)
Add interface index aka. scope id to struct kroute so that the rde can pass
this information to kroute and kroute can use that information to fill in the various sin6_scope_id fields.
-rw-r--r--usr.sbin/ospf6d/kroute.c38
-rw-r--r--usr.sbin/ospf6d/ospf6d.h5
-rw-r--r--usr.sbin/ospf6d/rde.c5
3 files changed, 34 insertions, 14 deletions
diff --git a/usr.sbin/ospf6d/kroute.c b/usr.sbin/ospf6d/kroute.c
index 5a96c0c5662..47580a98667 100644
--- a/usr.sbin/ospf6d/kroute.c
+++ b/usr.sbin/ospf6d/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.15 2009/12/21 18:35:43 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.16 2009/12/22 19:32:36 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -62,7 +62,7 @@ int kroute_compare(struct kroute_node *, struct kroute_node *);
struct kroute_node *kroute_find(const struct in6_addr *, u_int8_t);
struct kroute_node *kroute_matchgw(struct kroute_node *,
- struct in6_addr *);
+ struct in6_addr *, unsigned int);
int kroute_insert(struct kroute_node *);
int kroute_remove(struct kroute_node *);
void kroute_clear(void);
@@ -184,7 +184,8 @@ kr_change(struct kroute *kroute)
* Ingnore updates that did not change the route.
* Currently only the nexthop can change.
*/
- if (kr && IN6_ARE_ADDR_EQUAL(&kr->r.nexthop, &kroute->nexthop))
+ if (kr && kr->r.scope == kroute->scope &&
+ IN6_ARE_ADDR_EQUAL(&kr->r.nexthop, &kroute->nexthop))
return (0);
if (send_rtmsg(kr_state.fd, action, kroute) == -1)
@@ -198,14 +199,17 @@ kr_change(struct kroute *kroute)
kr->r.prefix = kroute->prefix;
kr->r.prefixlen = kroute->prefixlen;
kr->r.nexthop = kroute->nexthop;
+ kr->r.scope = kroute->scope;
kr->r.flags = kroute->flags | F_OSPFD_INSERTED;
kr->r.ext_tag = kroute->ext_tag;
kr->r.rtlabel = kroute->rtlabel;
if (kroute_insert(kr) == -1)
free(kr);
- } else if (kr)
+ } else if (kr) {
kr->r.nexthop = kroute->nexthop;
+ kr->r.scope = kroute->scope;
+ }
return (0);
}
@@ -502,10 +506,11 @@ kroute_find(const struct in6_addr *prefix, u_int8_t prefixlen)
}
struct kroute_node *
-kroute_matchgw(struct kroute_node *kr, struct in6_addr *nh)
+kroute_matchgw(struct kroute_node *kr, struct in6_addr *nh, unsigned int scope)
{
while (kr) {
- if (IN6_ARE_ADDR_EQUAL(&kr->r.nexthop, nh))
+ if (scope == kr->r.scope &&
+ IN6_ARE_ADDR_EQUAL(&kr->r.nexthop, nh))
return (kr);
kr = kr->next;
}
@@ -941,7 +946,7 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
bzero(&hdr, sizeof(hdr));
hdr.rtm_version = RTM_VERSION;
hdr.rtm_type = action;
- hdr.rtm_flags = RTF_PROTO2;
+ hdr.rtm_flags = RTF_UP|RTF_PROTO2;
hdr.rtm_priority = RTP_OSPF;
if (action == RTM_CHANGE) /* force PROTO2 reset the other flags */
hdr.rtm_fmask = RTF_PROTO2|RTF_PROTO1|RTF_REJECT|RTF_BLACKHOLE;
@@ -967,6 +972,7 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
nexthop.sin6_len = sizeof(nexthop);
nexthop.sin6_family = AF_INET6;
nexthop.sin6_addr = kroute->nexthop;
+ nexthop.sin6_scope_id = kroute->scope;
/* adjust header */
hdr.rtm_flags |= RTF_GATEWAY;
hdr.rtm_addrs |= RTA_GATEWAY;
@@ -981,6 +987,8 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
mask.sin6_family = AF_INET6;
mask.sin6_addr = *prefixlen2mask(kroute->prefixlen);
/* adjust header */
+ if (kroute->prefixlen == 128)
+ hdr.rtm_flags |= RTF_HOST;
hdr.rtm_addrs |= RTA_NETMASK;
hdr.rtm_msglen += sizeof(mask);
/* adjust iovec */
@@ -1121,6 +1129,8 @@ fetchtable(void)
case AF_INET6:
kr->r.nexthop =
((struct sockaddr_in6 *)sa)->sin6_addr;
+ kr->r.scope =
+ ((struct sockaddr_in6 *)sa)->sin6_scope_id;
break;
case AF_LINK:
kr->r.flags |= F_CONNECTED;
@@ -1236,6 +1246,7 @@ dispatch_rtmsg(void)
struct in6_addr prefix, nexthop;
u_int8_t prefixlen;
int flags, mpath;
+ unsigned int scope;
u_short ifindex = 0;
if ((n = read(kr_state.fd, &buf, sizeof(buf))) == -1) {
@@ -1256,6 +1267,7 @@ dispatch_rtmsg(void)
bzero(&prefix, sizeof(prefix));
bzero(&nexthop, sizeof(nexthop));
+ scope = 0;
prefixlen = 0;
flags = F_KERNEL;
mpath = 0;
@@ -1312,6 +1324,8 @@ dispatch_rtmsg(void)
case AF_INET6:
nexthop = ((struct sockaddr_in6 *)
sa)->sin6_addr;
+ scope = ((struct sockaddr_in6 *)
+ sa)->sin6_scope_id;
break;
case AF_LINK:
flags |= F_CONNECTED;
@@ -1323,7 +1337,7 @@ dispatch_rtmsg(void)
switch (rtm->rtm_type) {
case RTM_ADD:
case RTM_CHANGE:
- if (IN6_IS_ADDR_UNSPECIFIED(&nexthop) == 0 &&
+ if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop) &&
!(flags & F_CONNECTED)) {
log_warnx("dispatch_rtmsg no nexthop for %s/%u",
log_in6addr(&prefix), prefixlen);
@@ -1338,7 +1352,7 @@ dispatch_rtmsg(void)
/* get the correct route */
kr = okr;
if (mpath && (kr = kroute_matchgw(okr,
- &nexthop)) == NULL) {
+ &nexthop, scope)) == NULL) {
log_warnx("dispatch_rtmsg mpath route"
" not found");
/* add routes we missed out earlier */
@@ -1355,6 +1369,7 @@ dispatch_rtmsg(void)
if (kr->r.flags & F_REDISTRIBUTED)
flags |= F_REDISTRIBUTED;
kr->r.nexthop = nexthop;
+ kr->r.scope = scope;
kr->r.flags = flags;
kr->r.ifindex = ifindex;
@@ -1386,6 +1401,7 @@ add:
kr->r.prefix = prefix;
kr->r.prefixlen = prefixlen;
kr->r.nexthop = nexthop;
+ kr->r.scope = scope;
kr->r.flags = flags;
kr->r.ifindex = ifindex;
@@ -1408,8 +1424,8 @@ add:
continue;
/* get the correct route */
okr = kr;
- if (mpath &&
- (kr = kroute_matchgw(kr, &nexthop)) == NULL) {
+ if (mpath && (kr = kroute_matchgw(kr, &nexthop,
+ scope)) == NULL) {
log_warnx("dispatch_rtmsg mpath route"
" not found");
return (-1);
diff --git a/usr.sbin/ospf6d/ospf6d.h b/usr.sbin/ospf6d/ospf6d.h
index 2a0cfaa63bc..0859101ba2c 100644
--- a/usr.sbin/ospf6d/ospf6d.h
+++ b/usr.sbin/ospf6d/ospf6d.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf6d.h,v 1.18 2009/12/22 17:54:04 claudio Exp $ */
+/* $OpenBSD: ospf6d.h,v 1.19 2009/12/22 19:32:36 claudio Exp $ */
/*
* Copyright (c) 2004, 2007 Esben Norby <norby@openbsd.org>
@@ -375,9 +375,10 @@ struct ospfd_conf {
struct kroute {
struct in6_addr prefix;
struct in6_addr nexthop;
+ u_int32_t ext_tag;
+ unsigned int scope; /* scope of nexthop */
u_int16_t flags;
u_int16_t rtlabel;
- u_int32_t ext_tag;
u_short ifindex;
u_int8_t prefixlen;
};
diff --git a/usr.sbin/ospf6d/rde.c b/usr.sbin/ospf6d/rde.c
index 40c717fba7e..1585b739ef8 100644
--- a/usr.sbin/ospf6d/rde.c
+++ b/usr.sbin/ospf6d/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.34 2009/11/02 20:24:58 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.35 2009/12/22 19:32:36 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -812,6 +812,9 @@ rde_send_change_kroute(struct rt_node *r)
bzero(&kr, sizeof(kr));
kr.prefix = r->prefix;
kr.nexthop = rn->nexthop;
+ if (IN6_IS_ADDR_LINKLOCAL(&rn->nexthop) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(&rn->nexthop))
+ kr.scope = rn->ifindex;
kr.prefixlen = r->prefixlen;
kr.ext_tag = r->ext_tag;