mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
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.) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
3df31ebb03
commit
abffde07a3
|
@ -100,8 +100,10 @@ static void connected_announce(struct interface *ifp, struct connected *ifc)
|
|||
}
|
||||
|
||||
/* If same interface address is already exist... */
|
||||
struct connected *connected_check(struct interface *ifp, struct prefix *p)
|
||||
struct connected *connected_check(struct interface *ifp,
|
||||
union prefixconstptr pu)
|
||||
{
|
||||
const struct prefix *p = pu.p;
|
||||
struct connected *ifc;
|
||||
struct listnode *node;
|
||||
|
||||
|
@ -112,6 +114,33 @@ struct connected *connected_check(struct interface *ifp, struct prefix *p)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* same, but with peer address */
|
||||
struct connected *connected_check_ptp(struct interface *ifp,
|
||||
union prefixconstptr pu,
|
||||
union prefixconstptr du)
|
||||
{
|
||||
const struct prefix *p = pu.p;
|
||||
const struct prefix *d = du.p;
|
||||
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 in the same state */
|
||||
static int connected_same(struct connected *ifc1, struct connected *ifc2)
|
||||
{
|
||||
|
@ -145,7 +174,8 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
|
|||
struct connected *current;
|
||||
|
||||
/* Check same connected route. */
|
||||
if ((current = connected_check(ifp, (struct prefix *)ifc->address))) {
|
||||
current = connected_check_ptp(ifp, ifc->address, ifc->destination);
|
||||
if (current) {
|
||||
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
|
||||
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
||||
|
||||
|
@ -238,7 +268,8 @@ void 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. */
|
||||
|
@ -350,15 +381,25 @@ 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;
|
||||
|
||||
|
|
|
@ -23,7 +23,10 @@
|
|||
#define _ZEBRA_CONNECTED_H
|
||||
|
||||
extern struct connected *connected_check(struct interface *ifp,
|
||||
struct prefix *p);
|
||||
union prefixconstptr p);
|
||||
extern struct connected *connected_check_ptp(struct interface *ifp,
|
||||
union prefixconstptr p,
|
||||
union prefixconstptr d);
|
||||
|
||||
extern void connected_add_ipv4(struct interface *ifp, int flags,
|
||||
struct in_addr *addr, u_char prefixlen,
|
||||
|
|
|
@ -242,7 +242,7 @@ int 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);
|
||||
|
||||
|
@ -267,12 +267,16 @@ int 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)) {
|
||||
zlog_warn(
|
||||
"Trying to remove an address from an unknown subnet."
|
||||
|
@ -966,6 +970,8 @@ static void connected_dump_vty(struct vty *vty, struct connected *connected)
|
|||
vty_out(vty,
|
||||
(CONNECTED_PEER(connected) ? " peer " : " broadcast "));
|
||||
prefix_vty_out(vty, connected->destination);
|
||||
if (CONNECTED_PEER(connected))
|
||||
vty_out(vty, "/%d", connected->destination->prefixlen);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
|
||||
|
|
Loading…
Reference in a new issue