summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2010-01-30 12:10:23 +0100
committerDavid Lamparter <equinox@diac24.net>2010-02-03 05:24:58 +0100
commit4215c0117a843d324c7a33ac56244252f0f40ed6 (patch)
treeb370bc8f97dda6a6dc1e658eb5862d496a73b247 /zebra
parent63cf3e60162a47952d1578d574d7d9186df936c0 (diff)
downloadquagga-4215c0117a843d324c7a33ac56244252f0f40ed6.tar.bz2
quagga-4215c0117a843d324c7a33ac56244252f0f40ed6.tar.xz
zebra: add connected_check_ptp infrastructure
add a connected_check_ptp function which does the same as connected_check, but takes an additional peer prefix argument. also fix related prefixlen mixup in PtP addresses (the local part of a PtP address always is /32, but previously the peer mask got copied.)
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c47
-rw-r--r--zebra/connected.h2
-rw-r--r--zebra/interface.c9
3 files changed, 51 insertions, 7 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 95399fa1..bf5715e4 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -112,6 +112,30 @@ connected_check (struct interface *ifp, struct prefix *p)
return NULL;
}
+/* same, but with peer address */
+struct connected *
+connected_check_ptp (struct interface *ifp, struct prefix *p, struct prefix *d)
+{
+ struct connected *ifc;
+ struct listnode *node;
+
+ /* ignore broadcast addresses */
+ if (p->prefixlen != IPV4_MAX_PREFIXLEN)
+ d = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
+ {
+ if (!prefix_same (ifc->address, p))
+ continue;
+ if (!CONNECTED_PEER(ifc) && !d)
+ return ifc;
+ if (CONNECTED_PEER(ifc) && d && prefix_same (ifc->destination, d))
+ return ifc;
+ }
+
+ return NULL;
+}
+
/* Check if two ifc's describe the same address */
static int
connected_same (struct connected *ifc1, struct connected *ifc2)
@@ -148,7 +172,7 @@ connected_implicit_withdraw (struct interface *ifp, struct connected *ifc)
struct connected *current;
/* Check same connected route. */
- if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
+ if ((current = connected_check_ptp (ifp, ifc->address, ifc->destination)))
{
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
@@ -212,7 +236,8 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
p = prefix_ipv4_new ();
p->family = AF_INET;
p->prefix = *addr;
- p->prefixlen = prefixlen;
+ p->prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER)
+ ? IPV4_MAX_PREFIXLEN : prefixlen;
ifc->address = (struct prefix *) p;
/* If there is broadcast or peer address. */
@@ -305,15 +330,27 @@ void
connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
u_char prefixlen, struct in_addr *broad)
{
- struct prefix_ipv4 p;
+ struct prefix_ipv4 p, d;
struct connected *ifc;
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefix = *addr;
- p.prefixlen = prefixlen;
+ p.prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER)
+ ? IPV4_MAX_PREFIXLEN : prefixlen;
+
+ if (broad)
+ {
+ memset (&d, 0, sizeof (struct prefix_ipv4));
+ d.family = AF_INET;
+ d.prefix = *broad;
+ d.prefixlen = prefixlen;
+ ifc = connected_check_ptp (ifp, (struct prefix *) &p,
+ (struct prefix *) &d);
+ }
+ else
+ ifc = connected_check_ptp (ifp, (struct prefix *) &p, NULL);
- ifc = connected_check (ifp, (struct prefix *) &p);
if (! ifc)
return;
diff --git a/zebra/connected.h b/zebra/connected.h
index 9595ddb1..0f7c586b 100644
--- a/zebra/connected.h
+++ b/zebra/connected.h
@@ -25,6 +25,8 @@
extern struct connected *
connected_check (struct interface *ifp, struct prefix *p);
+extern struct connected *
+connected_check_ptp (struct interface *ifp, struct prefix *p, struct prefix *d);
extern void
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
diff --git a/zebra/interface.c b/zebra/interface.c
index aa078925..7c2fbe9c 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -127,7 +127,7 @@ if_subnet_add (struct interface *ifp, struct connected *ifc)
/* Get address derived subnet node and associated address list, while marking
address secondary attribute appropriately. */
- cp = *ifc->address;
+ cp = *CONNECTED_PREFIX(ifc);
apply_mask (&cp);
rn = route_node_get (zebra_if->ipv4_subnets, &cp);
@@ -154,12 +154,16 @@ if_subnet_delete (struct interface *ifp, struct connected *ifc)
struct route_node *rn;
struct zebra_if *zebra_if;
struct list *addr_list;
+ struct prefix cp;
assert (ifp && ifp->info && ifc);
zebra_if = ifp->info;
+ cp = *CONNECTED_PREFIX(ifc);
+ apply_mask (&cp);
+
/* Get address derived subnet node. */
- rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
+ rn = route_node_lookup (zebra_if->ipv4_subnets, &cp);
if (! (rn && rn->info))
return -1;
route_unlock_node (rn);
@@ -588,6 +592,7 @@ connected_dump_vty (struct vty *vty, struct connected *connected)
{
vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
prefix_vty_out (vty, connected->destination);
+ vty_out (vty, "/%d", connected->destination->prefixlen);
}
if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))