diff options
author | David Lamparter <equinox@diac24.net> | 2010-01-30 12:10:23 +0100 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2010-02-03 05:24:58 +0100 |
commit | 4215c0117a843d324c7a33ac56244252f0f40ed6 (patch) | |
tree | b370bc8f97dda6a6dc1e658eb5862d496a73b247 /zebra | |
parent | 63cf3e60162a47952d1578d574d7d9186df936c0 (diff) | |
download | quagga-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.c | 47 | ||||
-rw-r--r-- | zebra/connected.h | 2 | ||||
-rw-r--r-- | zebra/interface.c | 9 |
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)) |