mirror of
https://github.com/FRRouting/frr.git
synced 2025-05-01 05:57:15 +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... */
|
/* 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 connected *ifc;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
|
||||||
|
@ -112,6 +114,33 @@ struct connected *connected_check(struct interface *ifp, struct prefix *p)
|
||||||
return NULL;
|
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 */
|
/* Check if two ifc's describe the same address in the same state */
|
||||||
static int connected_same(struct connected *ifc1, struct connected *ifc2)
|
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;
|
struct connected *current;
|
||||||
|
|
||||||
/* Check same connected route. */
|
/* 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))
|
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
|
||||||
SET_FLAG(ifc->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 = prefix_ipv4_new();
|
||||||
p->family = AF_INET;
|
p->family = AF_INET;
|
||||||
p->prefix = *addr;
|
p->prefix = *addr;
|
||||||
p->prefixlen = prefixlen;
|
p->prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
|
||||||
|
: prefixlen;
|
||||||
ifc->address = (struct prefix *)p;
|
ifc->address = (struct prefix *)p;
|
||||||
|
|
||||||
/* If there is broadcast or peer address. */
|
/* 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 *addr, u_char prefixlen,
|
||||||
struct in_addr *broad)
|
struct in_addr *broad)
|
||||||
{
|
{
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p, d;
|
||||||
struct connected *ifc;
|
struct connected *ifc;
|
||||||
|
|
||||||
memset(&p, 0, sizeof(struct prefix_ipv4));
|
memset(&p, 0, sizeof(struct prefix_ipv4));
|
||||||
p.family = AF_INET;
|
p.family = AF_INET;
|
||||||
p.prefix = *addr;
|
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)
|
if (!ifc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,10 @@
|
||||||
#define _ZEBRA_CONNECTED_H
|
#define _ZEBRA_CONNECTED_H
|
||||||
|
|
||||||
extern struct connected *connected_check(struct interface *ifp,
|
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,
|
extern void connected_add_ipv4(struct interface *ifp, int flags,
|
||||||
struct in_addr *addr, u_char prefixlen,
|
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
|
/* Get address derived subnet node and associated address list, while
|
||||||
marking
|
marking
|
||||||
address secondary attribute appropriately. */
|
address secondary attribute appropriately. */
|
||||||
cp = *ifc->address;
|
cp = *CONNECTED_PREFIX(ifc);
|
||||||
apply_mask(&cp);
|
apply_mask(&cp);
|
||||||
rn = route_node_get(zebra_if->ipv4_subnets, &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 route_node *rn;
|
||||||
struct zebra_if *zebra_if;
|
struct zebra_if *zebra_if;
|
||||||
struct list *addr_list;
|
struct list *addr_list;
|
||||||
|
struct prefix cp;
|
||||||
|
|
||||||
assert(ifp && ifp->info && ifc);
|
assert(ifp && ifp->info && ifc);
|
||||||
zebra_if = ifp->info;
|
zebra_if = ifp->info;
|
||||||
|
|
||||||
|
cp = *CONNECTED_PREFIX(ifc);
|
||||||
|
apply_mask(&cp);
|
||||||
|
|
||||||
/* Get address derived subnet node. */
|
/* 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)) {
|
if (!(rn && rn->info)) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"Trying to remove an address from an unknown subnet."
|
"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,
|
vty_out(vty,
|
||||||
(CONNECTED_PEER(connected) ? " peer " : " broadcast "));
|
(CONNECTED_PEER(connected) ? " peer " : " broadcast "));
|
||||||
prefix_vty_out(vty, connected->destination);
|
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))
|
if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
|
||||||
|
|
Loading…
Reference in a new issue