more correct advert for global address on p2p.

avoid reusing upper bits of rtm_flags.  (sync with kame)
This commit is contained in:
itojun 2000-05-18 13:23:43 +00:00
parent 56b2a497b1
commit c3b1168f43
1 changed files with 51 additions and 40 deletions

View File

@ -1,5 +1,5 @@
/* $NetBSD: route6d.c,v 1.12 2000/05/16 14:04:32 itojun Exp $ */
/* $KAME: route6d.c,v 1.19 2000/05/16 13:10:39 itojun Exp $ */
/* $NetBSD: route6d.c,v 1.13 2000/05/18 13:23:43 itojun Exp $ */
/* $KAME: route6d.c,v 1.25 2000/05/17 09:05:36 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: route6d.c,v 1.12 2000/05/16 14:04:32 itojun Exp $");
__RCSID("$NetBSD: route6d.c,v 1.13 2000/05/18 13:23:43 itojun Exp $");
#endif
#include <stdio.h>
@ -166,7 +166,8 @@ struct riprt {
struct riprt *rrt_same; /* same destination - future use */
struct netinfo6 rrt_info; /* network info */
struct in6_addr rrt_gw; /* gateway */
u_long rrt_flags;
u_long rrt_flags; /* kernel routing table flags */
u_long rrt_rflags; /* route6d routing table flags */
time_t rrt_t; /* when the route validated */
int rrt_index; /* ifindex from which this route got */
};
@ -203,12 +204,11 @@ int logopened = 0;
static u_long seq = 0;
#define RTF_AGGREGATE 0x08000000
#define RTF_NOADVERTISE 0x10000000
#define RTF_NH_NOT_LLADDR 0x20000000
#define RTF_SENDANYWAY 0x40000000
#define RTF_CHANGED 0x80000000
#define RTF_ROUTE_H 0xffff
#define RRTF_AGGREGATE 0x08000000
#define RRTF_NOADVERTISE 0x10000000
#define RRTF_NH_NOT_LLADDR 0x20000000
#define RRTF_SENDANYWAY 0x40000000
#define RRTF_CHANGED 0x80000000
int main __P((int, char **));
void ripalarm __P((int));
@ -446,7 +446,7 @@ rtdexit(sig)
alarm(0);
for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
if (rrt->rrt_flags & RTF_AGGREGATE) {
if (rrt->rrt_rflags & RRTF_AGGREGATE) {
delroute(&rrt->rrt_info, &rrt->rrt_gw);
}
}
@ -665,7 +665,7 @@ ripsend(ifcp, sin, flag)
sizeof(struct netinfo6);
nrt = 0; np = ripbuf->rip6_nets; nh = NULL;
for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
if (rrt->rrt_flags & RTF_NOADVERTISE)
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
continue;
/* Put the route to the buffer */
*np = rrt->rrt_info;
@ -680,7 +680,7 @@ ripsend(ifcp, sin, flag)
return;
}
if ((flag & RTF_SENDANYWAY) == 0 &&
if ((flag & RRTF_SENDANYWAY) == 0 &&
(qflag || (ifcp->ifc_flags & IFF_LOOPBACK)))
return;
if (iff_find(ifcp, 'N') != NULL)
@ -704,7 +704,7 @@ ripsend(ifcp, sin, flag)
sizeof(struct netinfo6);
nrt = 0; np = ripbuf->rip6_nets; nh = NULL;
for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
if (rrt->rrt_flags & RTF_NOADVERTISE)
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
continue;
/* Need to check filer here */
ok = 1;
@ -741,12 +741,13 @@ ripsend(ifcp, sin, flag)
if (tobeadv(rrt, ifcp) == 0)
continue;
/* Only considers the routes with flag if specified */
if ((flag & RTF_CHANGED) && (rrt->rrt_flags & RTF_CHANGED) == 0)
if ((flag & RRTF_CHANGED) &&
(rrt->rrt_rflags & RRTF_CHANGED) == 0)
continue;
/* Check nexthop */
if (rrt->rrt_index == ifcp->ifc_index &&
!IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_gw) &&
(rrt->rrt_flags & RTF_NH_NOT_LLADDR) == 0) {
(rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) == 0) {
if (nh == NULL || !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw)) {
if (nrt == maxrte - 2)
ripflush(ifcp, sin);
@ -761,7 +762,7 @@ ripsend(ifcp, sin, flag)
}
} else if (nh && (rrt->rrt_index != ifcp->ifc_index ||
!IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw) ||
rrt->rrt_flags & RTF_NH_NOT_LLADDR)) {
rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)) {
/* Reset nexthop */
if (nrt == maxrte - 2)
ripflush(ifcp, sin);
@ -1086,7 +1087,7 @@ riprecv()
*nq = *np;
addroute(rrt, &nh, ifcp);
}
rrt->rrt_flags |= RTF_CHANGED;
rrt->rrt_rflags |= RRTF_CHANGED;
rrt->rrt_t = t;
need_trigger = 1;
} else if (nq->rip6_metric < np->rip6_metric &&
@ -1095,7 +1096,7 @@ riprecv()
/* Got worse route from same gw */
nq->rip6_metric = np->rip6_metric;
rrt->rrt_t = t;
rrt->rrt_flags |= RTF_CHANGED;
rrt->rrt_rflags |= RRTF_CHANGED;
need_trigger = 1;
} else if (nq->rip6_metric == np->rip6_metric &&
rrt->rrt_index == ifcp->ifc_index &&
@ -1129,7 +1130,7 @@ riprecv()
riprt = rrt;
/* Update routing table */
addroute(rrt, &nh, ifcp);
rrt->rrt_flags |= RTF_CHANGED;
rrt->rrt_rflags |= RRTF_CHANGED;
need_trigger = 1;
rrt->rrt_t = t;
}
@ -1142,12 +1143,12 @@ riprecv()
continue;
if (ic->ifc_flags & IFF_UP)
ripsend(ic, &ic->ifc_ripsin,
RTF_CHANGED);
RRTF_CHANGED);
}
}
/* Reset the flag */
for (rrt = riprt; rrt; rrt = rrt->rrt_next)
rrt->rrt_flags &= ~RTF_CHANGED;
rrt->rrt_rflags &= ~RRTF_CHANGED;
}
}
@ -1209,7 +1210,7 @@ riprequest(ifcp, np, nn, sin)
}
/* Whole routing table dump */
trace(1, "\tRIP Request -- whole routing table\n");
ripsend(ifcp, sin, RTF_SENDANYWAY);
ripsend(ifcp, sin, RRTF_SENDANYWAY);
}
/*
@ -1926,7 +1927,8 @@ ifrt(ifcp, again)
/*
* there are couple of p2p interface routing models. "behavior" lets
* you pick one.
* you pick one. it looks that gated behavior fits best with BSDs,
* since BSD kernels does not look at prefix length on p2p interfaces.
*/
void
ifrt_p2p(ifcp, again)
@ -1937,7 +1939,7 @@ ifrt_p2p(ifcp, again)
struct riprt *rrt;
struct netinfo6 *np;
struct in6_addr addr, dest;
int advert, i;
int advert, ignore, i;
#define P2PADVERT_NETWORK 1
#define P2PADVERT_ADDR 2
#define P2PADVERT_DEST 4
@ -1951,25 +1953,30 @@ ifrt_p2p(ifcp, again)
dest = ifa->ifa_raddr;
applyplen(&addr, ifa->ifa_plen);
applyplen(&dest, ifa->ifa_plen);
advert = ignore = 0;
switch (behavior) {
case CISCO:
/*
* advertise addr/plen, treating p2p interface
* just like shared medium interface.
* this may cause trouble if you reuse addr/plen
* in other places.
* honor addr/plen, just like normal shared medium
* interface. this may cause trouble if you reuse
* addr/plen on other interfaces.
*
* advertise addr/plen.
*/
advert |= P2PADVERT_NETWORK;
break;
case GATED:
/*
* advertise dest/128. since addr/128 is not
* advertised, addr/128 is not reachable from other
* interfaces (if p2p interface is A, addr/128 is not
* reachable from other interfaces). not sure why it
* is not advertised.
* prefixlen on p2p interface is meaningless.
* advertise addr/128 and dest/128.
*
* do not install network route to route6d routing
* table (if we do, it would prevent route installation
* for other p2p interface that shares addr/plen).
*/
advert |= P2PADVERT_ADDR;
advert |= P2PADVERT_DEST;
ignore |= P2PADVERT_NETWORK;
break;
case ROUTE6D:
/*
@ -1980,11 +1987,14 @@ ifrt_p2p(ifcp, again)
else {
advert |= P2PADVERT_ADDR;
advert |= P2PADVERT_DEST;
ignore |= P2PADVERT_NETWORK;
}
break;
}
for (i = 1; i <= P2PADVERT_MAX; i *= 2) {
if ((ignore & i) != 0)
continue;
if ((rrt = MALLOC(struct riprt)) == NULL)
fatal("malloc: struct riprt");
memset(rrt, 0, sizeof(*rrt));
@ -2020,7 +2030,7 @@ ifrt_p2p(ifcp, again)
continue;
}
if ((advert & i) == 0) {
rrt->rrt_flags |= RTF_NOADVERTISE;
rrt->rrt_rflags |= RRTF_NOADVERTISE;
noadv = ", NO-ADV";
} else
noadv = "";
@ -2349,7 +2359,7 @@ rt_entry(rtm, again)
inet6_n2p(&rrt->rrt_gw));
trace(0, "***** dest(%s) if(%s) -- Not optimized.\n",
inet6_n2p(&rrt->rrt_info.rip6_dest), ifname);
rrt->rrt_flags |= RTF_NH_NOT_LLADDR;
rrt->rrt_rflags |= RRTF_NH_NOT_LLADDR;
}
/* Put it to the route list */
@ -2388,7 +2398,7 @@ addroute(rrt, gw, ifcp)
rtm->rtm_version = RTM_VERSION;
rtm->rtm_seq = ++seq;
rtm->rtm_pid = pid;
rtm->rtm_flags = rrt->rrt_flags & RTF_ROUTE_H;
rtm->rtm_flags = rrt->rrt_flags;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
rtm->rtm_rmx.rmx_hopcount = np->rip6_metric - 1;
rtm->rtm_inits = RTV_HOPCOUNT;
@ -2690,9 +2700,9 @@ rtdump(sig)
fprintf(dump, " tag(0x%04x)",
ntohs(rrt->rrt_info.rip6_tag) & 0xffff);
}
if (rrt->rrt_flags & RTF_NH_NOT_LLADDR)
if (rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)
fprintf(dump, " NOT-LL");
if (rrt->rrt_flags & RTF_NOADVERTISE)
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
fprintf(dump, " NO-ADV");
fprintf(dump, "\n");
}
@ -2770,7 +2780,8 @@ ifonly:
rrt->rrt_info.rip6_metric = 1;
rrt->rrt_info.rip6_tag = htons(routetag & 0xffff);
rrt->rrt_gw = in6addr_loopback;
rrt->rrt_flags = RTF_UP | RTF_REJECT | RTF_AGGREGATE;
rrt->rrt_flags = RTF_UP | RTF_REJECT;
rrt->rrt_rflags = RRTF_AGGREGATE;
rrt->rrt_t = 0;
rrt->rrt_index = loopifindex;
/* Put the route to the list */