summaryrefslogtreecommitdiffstats
path: root/nest
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>2000-03-01 00:19:52 +0100
committerMartin Mares <mj@ucw.cz>2000-03-01 00:19:52 +0100
commit6a636392d33627944df9d5a9573932cdc0bf6da5 (patch)
tree9e689378151af5a882085356ba7d3bb3ebabcbbb /nest
parente69e4ed9349ee28262fe74f70e7e52c181d5d098 (diff)
downloadbird-6a636392d33627944df9d5a9573932cdc0bf6da5.tar
bird-6a636392d33627944df9d5a9573932cdc0bf6da5.zip
Rewrote interface type detection logic. The `unnumbered' flag is now per
address, not per interface (hence it's ifa->flags & IA_UNNUMBERED) and should be set reliably. IF_MULTIACCESS should be fixed now, but it isn't wise to rely on it on interfaces configured with /30 prefix.
Diffstat (limited to 'nest')
-rw-r--r--nest/iface.c55
-rw-r--r--nest/iface.h14
-rw-r--r--nest/rt-dev.c5
3 files changed, 43 insertions, 31 deletions
diff --git a/nest/iface.c b/nest/iface.c
index ce233cd..9b4eff0 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -36,16 +36,25 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
if (!(i->flags & IF_UP))
return 0;
- if ((i->flags & IF_UNNUMBERED) && ipa_equal(*a, i->addr->opposite))
- return 1;
WALK_LIST(b, i->addrs)
- if (ipa_in_net(*a, b->prefix, b->pxlen))
- {
- if (ipa_equal(*a, b->prefix) || /* Network address */
- ipa_equal(*a, b->brd) || /* Broadcast */
- ipa_equal(*a, b->ip)) /* Our own address */
- return -1;
- return 1;
+ {
+ if (ipa_equal(*a, b->ip))
+ return -1;
+ if (b->flags & IA_UNNUMBERED)
+ {
+ if (ipa_equal(*a, b->opposite))
+ return 1;
+ }
+ else
+ {
+ if (ipa_in_net(*a, b->prefix, b->pxlen))
+ {
+ if (ipa_equal(*a, b->prefix) || /* Network address */
+ ipa_equal(*a, b->brd)) /* Broadcast */
+ return -1;
+ return 1;
+ }
+ }
}
return 0;
}
@@ -184,9 +193,10 @@ list iface_list;
void
ifa_dump(struct ifa *a)
{
- debug("\t%I, net %I/%-2d bc %I -> %I%s%s\n", a->ip, a->prefix, a->pxlen, a->brd, a->opposite,
+ debug("\t%I, net %I/%-2d bc %I -> %I%s%s%s\n", a->ip, a->prefix, a->pxlen, a->brd, a->opposite,
(a->flags & IF_UP) ? "" : " DOWN",
- (a->flags & IA_PRIMARY) ? "" : " SEC");
+ (a->flags & IA_PRIMARY) ? "" : " SEC",
+ (a->flags & IA_UNNUMBERED) ? " UNNUM" : "");
}
void
@@ -205,8 +215,6 @@ if_dump(struct iface *i)
debug(" LINK-UP");
if (i->flags & IF_MULTIACCESS)
debug(" MA");
- if (i->flags & IF_UNNUMBERED)
- debug(" UNNUM");
if (i->flags & IF_BROADCAST)
debug(" BC");
if (i->flags & IF_MULTICAST)
@@ -492,7 +500,8 @@ ifa_update(struct ifa *a)
b->pxlen == a->pxlen &&
ipa_equal(b->brd, a->brd) &&
ipa_equal(b->opposite, a->opposite) &&
- b->scope == a->scope)
+ b->scope == a->scope &&
+ !((b->flags ^ a->flags) & IA_UNNUMBERED))
{
b->flags |= IF_UPDATED;
return b;
@@ -500,6 +509,12 @@ ifa_update(struct ifa *a)
ifa_delete(b);
break;
}
+
+ if (!(i->flags & IF_MULTIACCESS) && a->pxlen < BITS_PER_IP_ADDRESS - 2)
+ log(L_WARN "Strange prefix length %d for point-to-point interface %s", a->pxlen, i->name);
+ if ((i->flags & IF_BROADCAST) && !ipa_nonzero(a->brd))
+ log(L_ERR "Missing broadcast address for interface %s", i->name);
+
b = mb_alloc(if_pool, sizeof(struct ifa));
memcpy(b, a, sizeof(struct ifa));
add_tail(&i->addrs, &b->n);
@@ -545,8 +560,9 @@ auto_router_id(void)
j = NULL;
WALK_LIST(i, iface_list)
if ((i->flags & IF_LINK_UP) &&
- !(i->flags & (IF_UNNUMBERED | IF_IGNORE | IF_ADMIN_DOWN)) &&
+ !(i->flags & (IF_IGNORE | IF_ADMIN_DOWN)) &&
i->addr &&
+ !(i->addr->flags & IA_UNNUMBERED) &&
(!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip)))
j = i;
if (!j)
@@ -633,11 +649,12 @@ if_show_addr(struct ifa *a)
bsprintf(opp, ", opposite %I", a->opposite);
else
opp[0] = 0;
- cli_msg(-1003, "\t%I/%d (%s%s%s, scope %s)",
+ cli_msg(-1003, "\t%I/%d (%s%s%s, scope %s%s)",
a->ip, a->pxlen,
(a->flags & IA_PRIMARY) ? "Primary" : (a->flags & IA_SECONDARY) ? "Secondary" : "???",
broad, opp,
- ip_scope_text(a->scope));
+ ip_scope_text(a->scope),
+ (a->flags & IA_UNNUMBERED) ? ", unnumbered" : "");
}
void
@@ -650,9 +667,7 @@ if_show(void)
WALK_LIST(i, iface_list)
{
cli_msg(-1001, "%s %s (index=%d)", i->name, (i->flags & IF_UP) ? "up" : "DOWN", i->index);
- if (i->flags & IF_UNNUMBERED)
- type = "UnNum-PtP";
- else if (!(i->flags & IF_MULTIACCESS))
+ if (!(i->flags & IF_MULTIACCESS))
type = "PtP";
else
type = "MultiAccess";
diff --git a/nest/iface.h b/nest/iface.h
index b13ec71..5ac9f2f 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -40,16 +40,16 @@ struct iface {
#define IF_UP 1 /* IF_LINK_UP and IP address known */
#define IF_MULTIACCESS 2
-#define IF_UNNUMBERED 4
-#define IF_BROADCAST 8
-#define IF_MULTICAST 0x10
-#define IF_ADMIN_DOWN 0x40
-#define IF_LOOPBACK 0x80
-#define IF_IGNORE 0x100 /* Not to be used by routing protocols (loopbacks etc.) */
-#define IF_LINK_UP 0x200
+#define IF_BROADCAST 4
+#define IF_MULTICAST 8
+#define IF_ADMIN_DOWN 0x10
+#define IF_LOOPBACK 0x20
+#define IF_IGNORE 0x40 /* Not to be used by routing protocols (loopbacks etc.) */
+#define IF_LINK_UP 0x80
#define IA_PRIMARY 0x10000 /* This address is primary */
#define IA_SECONDARY 0x20000 /* This address has been reported as secondary by the kernel */
+#define IA_UNNUMBERED 0x40000 /* This address belongs to an unnumbered device */
#define IA_FLAGS 0xff0000
#define IF_JUST_CREATED 0x10000000 /* Send creation event as soon as possible */
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index b9253cc..edadeba 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -56,10 +56,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
A.iface = ad->iface;
A.eattrs = NULL;
a = rta_lookup(&A);
- if (ad->flags & IF_UNNUMBERED)
- n = net_get(p->table, ad->opposite, ad->pxlen);
- else
- n = net_get(p->table, ad->prefix, ad->pxlen);
+ n = net_get(p->table, ad->prefix, ad->pxlen);
e = rte_get_temp(a);
e->net = n;
e->pflags = 0;