[zebra 14631] Generic PtP and RFC3021 interface addressing support

This commit is contained in:
paul 2002-12-13 21:07:36 +00:00
parent 8bd9c71436
commit 00df0c1e80
9 changed files with 67 additions and 165 deletions

View file

@ -663,7 +663,7 @@ bgp_connected_add (struct connected *ifc)
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p.u.prefix4 = dest->u.prefix4; p.u.prefix4 = dest->u.prefix4;
else else
p.u.prefix4 = addr->u.prefix4; p.u.prefix4 = addr->u.prefix4;
@ -694,7 +694,7 @@ bgp_connected_add (struct connected *ifc)
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p.u.prefix6 = dest->u.prefix6; p.u.prefix6 = dest->u.prefix6;
else else
p.u.prefix6 = addr->u.prefix6; p.u.prefix6 = addr->u.prefix6;
@ -748,7 +748,7 @@ bgp_connected_delete (struct connected *ifc)
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p.u.prefix4 = dest->u.prefix4; p.u.prefix4 = dest->u.prefix4;
else else
p.u.prefix4 = addr->u.prefix4; p.u.prefix4 = addr->u.prefix4;
@ -779,7 +779,7 @@ bgp_connected_delete (struct connected *ifc)
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p.u.prefix6 = dest->u.prefix6; p.u.prefix6 = dest->u.prefix6;
else else
p.u.prefix6 = addr->u.prefix6; p.u.prefix6 = addr->u.prefix6;

View file

@ -189,11 +189,13 @@ if_lookup_address (struct in_addr src)
listnode node; listnode node;
struct prefix addr; struct prefix addr;
struct prefix best; struct prefix best;
struct prefix peer;
listnode cnode; listnode cnode;
struct interface *ifp; struct interface *ifp;
struct prefix *p; struct prefix *p;
struct connected *c; struct connected *c;
struct interface *match; struct interface *match;
int prefixlen;
/* Zero structures - get rid of rubbish from stack */ /* Zero structures - get rid of rubbish from stack */
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
@ -212,34 +214,24 @@ if_lookup_address (struct in_addr src)
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{ {
c = getdata (cnode); c = getdata (cnode);
p = c->address;
if (if_is_pointopoint (ifp)) if (p->family == AF_INET)
{ {
p = c->address; prefixlen = p->prefixlen;
if (p && p->family == AF_INET) if (if_is_pointopoint (ifp) ||
prefixlen >= IPV4_MAX_PREFIXLEN - 1)
{ {
#ifdef OLD_RIB /* PTP links are conventionally identified peer = *c->destination;
by the address of the far end - MAG */ peer.prefixlen = prefixlen;
if (IPV4_ADDR_SAME (&p->u.prefix4, &src)) p = &peer;
return ifp;
#endif
p = c->destination;
if (p && IPV4_ADDR_SAME (&p->u.prefix4, &src))
return ifp;
} }
}
else
{
p = c->address;
if (p->family == AF_INET) if (prefix_match (p, &addr) && prefixlen > best.prefixlen)
{ {
if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen) best = *p;
{ match = ifp;
best = *p;
match = ifp;
}
} }
} }
} }

View file

@ -1413,7 +1413,7 @@ ospf_snmp_if_update (struct interface *ifp)
/* Lookup first IPv4 address entry. */ /* Lookup first IPv4 address entry. */
LIST_LOOP (ifp->connected, ifc, nn) LIST_LOOP (ifp->connected, ifc, nn)
{ {
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p = ifc->destination; p = ifc->destination;
else else
p = ifc->address; p = ifc->address;

View file

@ -699,17 +699,17 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
struct connected *co = getdata (cn); struct connected *co = getdata (cn);
struct prefix *addr; struct prefix *addr;
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (co))
addr = co->destination; addr = co->destination;
else else
addr = co->address; addr = co->address;
if (p->family == co->address->family && if (p->family == co->address->family &&
! ospf_if_is_configured (&(addr->u.prefix4))) ! ospf_if_is_configured (&(addr->u.prefix4)))
if ((if_is_pointopoint (ifp) && if ((ifc_pointopoint (co) &&
IPV4_ADDR_SAME (&(addr->u.prefix4), &(p->u.prefix4))) || IPV4_ADDR_SAME (&(addr->u.prefix4), &(p->u.prefix4))) ||
prefix_match (p, addr)) prefix_match (p, addr))
{ {
struct ospf_interface *oi; struct ospf_interface *oi;
oi = ospf_if_new (ifp, co->address); oi = ospf_if_new (ifp, co->address);

View file

@ -392,106 +392,6 @@ rip_if_ipv4_address_check (struct interface *ifp)
return count; return count;
} }
/* Does this address belongs to me ? */
int
if_check_address (struct in_addr addr)
{
listnode node;
for (node = listhead (iflist); node; nextnode (node))
{
listnode cnode;
struct interface *ifp;
ifp = getdata (node);
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{
struct connected *connected;
struct prefix_ipv4 *p;
connected = getdata (cnode);
p = (struct prefix_ipv4 *) connected->address;
if (p->family != AF_INET)
continue;
if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
return 1;
}
}
return 0;
}
/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
int
if_valid_neighbor (struct in_addr addr)
{
listnode node;
struct connected *connected = NULL;
struct prefix_ipv4 *p;
for (node = listhead (iflist); node; nextnode (node))
{
listnode cnode;
struct interface *ifp;
ifp = getdata (node);
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{
struct prefix *pxn = NULL; /* Prefix of the neighbor */
struct prefix *pxc = NULL; /* Prefix of the connected network */
connected = getdata (cnode);
if (if_is_pointopoint (ifp))
{
p = (struct prefix_ipv4 *) connected->address;
if (p && p->family == AF_INET)
{
if (IPV4_ADDR_SAME (&p->prefix, &addr))
return 1;
p = (struct prefix_ipv4 *) connected->destination;
if (p && IPV4_ADDR_SAME (&p->prefix, &addr))
return 1;
}
}
else
{
p = (struct prefix_ipv4 *) connected->address;
if (p->family != AF_INET)
continue;
pxn = prefix_new();
pxn->family = AF_INET;
pxn->prefixlen = 32;
pxn->u.prefix4 = addr;
pxc = prefix_new();
prefix_copy(pxc, (struct prefix *) p);
apply_mask(pxc);
if (prefix_match (pxc, pxn))
{
prefix_free (pxn);
prefix_free (pxc);
return 1;
}
prefix_free(pxc);
prefix_free(pxn);
}
}
}
return 0;
}
/* Inteface link down message processing. */ /* Inteface link down message processing. */
int int
rip_interface_down (int command, struct zclient *zclient, zebra_size_t length) rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)

View file

@ -976,7 +976,7 @@ rip_response_process (struct rip_packet *packet, int size,
/* The datagram's IPv4 source address should be checked to see /* The datagram's IPv4 source address should be checked to see
whether the datagram is from a valid neighbor; the source of the whether the datagram is from a valid neighbor; the source of the
datagram must be on a directly connected network */ datagram must be on a directly connected network */
if (! if_valid_neighbor (from->sin_addr)) if (if_lookup_address (from->sin_addr) == NULL)
{ {
zlog_info ("This datagram doesn't came from a valid neighbor: %s", zlog_info ("This datagram doesn't came from a valid neighbor: %s",
inet_ntoa (from->sin_addr)); inet_ntoa (from->sin_addr));
@ -1535,7 +1535,7 @@ rip_read (struct thread *t)
} }
/* Check is this packet comming from myself? */ /* Check is this packet comming from myself? */
if (if_check_address (from.sin_addr)) if (if_lookup_exact_address (from.sin_addr))
{ {
if (IS_RIP_DEBUG_PACKET) if (IS_RIP_DEBUG_PACKET)
zlog_warn ("ignore packet comes from myself"); zlog_warn ("ignore packet comes from myself");

View file

@ -359,8 +359,6 @@ void rip_zclient_init ();
void rip_zclient_start (); void rip_zclient_start ();
void rip_zclient_reset (); void rip_zclient_reset ();
void rip_offset_init (); void rip_offset_init ();
int if_check_address (struct in_addr addr);
int if_valid_neighbor (struct in_addr addr);
int rip_request_send (struct sockaddr_in *, struct interface *, u_char); int rip_request_send (struct sockaddr_in *, struct interface *, u_char);
int rip_neighbor_lookup (struct sockaddr_in *); int rip_neighbor_lookup (struct sockaddr_in *);

View file

@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
/* Point-to-point check. */ /* Point-to-point check. */
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p.prefix = dest->prefix; p.prefix = dest->prefix;
else else
p.prefix = addr->prefix; p.prefix = addr->prefix;
@ -162,7 +162,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp)) if (ifc_pointopoint (ifc))
p.prefix = dest->prefix; p.prefix = dest->prefix;
else else
p.prefix = addr->prefix; p.prefix = addr->prefix;
@ -249,7 +249,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp) && dest) if (ifc_pointopoint (ifc) && dest)
{ {
if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
p.prefix = addr->prefix; p.prefix = addr->prefix;
@ -339,7 +339,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = addr->prefixlen; p.prefixlen = addr->prefixlen;
if (if_is_pointopoint (ifp) && dest) if (ifc_pointopoint (ifc) && dest)
{ {
if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
p.prefix = addr->prefix; p.prefix = addr->prefix;

View file

@ -388,6 +388,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
void *broad = NULL; void *broad = NULL;
u_char flags = 0; u_char flags = 0;
char *label = NULL; char *label = NULL;
int peeronly = 0;
ifa = NLMSG_DATA (h); ifa = NLMSG_DATA (h);
@ -416,40 +417,51 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
return -1; return -1;
} }
if (tb[IFA_ADDRESS] == NULL) if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
tb[IFA_ADDRESS] = tb[IFA_LOCAL];
if (ifp->flags & IFF_POINTOPOINT)
{ {
char buf[BUFSIZ];
zlog_info ("netlink_interface_addr %s %s/%d:",
lookup (nlmsg_str, h->nlmsg_type),
ifp->name, ifa->ifa_prefixlen);
if (tb[IFA_LOCAL]) if (tb[IFA_LOCAL])
{ zlog_info (" IFA_LOCAL %s", inet_ntop (ifa->ifa_family,
addr = RTA_DATA (tb[IFA_LOCAL]); RTA_DATA (tb[IFA_LOCAL]), buf, BUFSIZ));
if (tb[IFA_ADDRESS])
broad = RTA_DATA (tb[IFA_ADDRESS]);
else
broad = NULL;
}
else
{
if (tb[IFA_ADDRESS])
addr = RTA_DATA (tb[IFA_ADDRESS]);
else
addr = NULL;
}
}
else
{
if (tb[IFA_ADDRESS]) if (tb[IFA_ADDRESS])
addr = RTA_DATA (tb[IFA_ADDRESS]); zlog_info (" IFA_ADDRESS %s", inet_ntop (ifa->ifa_family,
else RTA_DATA (tb[IFA_ADDRESS]), buf, BUFSIZ));
addr = NULL;
if (tb[IFA_BROADCAST]) if (tb[IFA_BROADCAST])
broad = RTA_DATA(tb[IFA_BROADCAST]); zlog_info (" IFA_BROADCAST %s", inet_ntop (ifa->ifa_family,
else RTA_DATA (tb[IFA_BROADCAST]), buf, BUFSIZ));
broad = NULL; if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
zlog_info (" IFA_LABEL %s", RTA_DATA (tb[IFA_LABEL]));
} }
/* peer or broadcast network? */
if (ifa->ifa_family == AF_INET)
peeronly = if_is_pointopoint (ifp) ||
ifa->ifa_prefixlen >= IPV4_MAX_PREFIXLEN - 1;
#ifdef HAVE_IPV6
if (ifa->ifa_family == AF_INET6)
peeronly = if_is_pointopoint (ifp) ||
ifa->ifa_prefixlen >= IPV6_MAX_PREFIXLEN - 1;
#endif /* HAVE_IPV6*/
/* network. prefixlen applies to IFA_ADDRESS rather than IFA_LOCAL */
if (tb[IFA_ADDRESS] && !peeronly)
addr = RTA_DATA (tb[IFA_ADDRESS]);
else if (tb[IFA_LOCAL])
addr = RTA_DATA (tb[IFA_LOCAL]);
else
addr = NULL;
/* broadcast/peer */
if (tb[IFA_BROADCAST])
broad = RTA_DATA (tb[IFA_BROADCAST]);
else if (tb[IFA_ADDRESS] && peeronly)
broad = RTA_DATA (tb[IFA_ADDRESS]); /* peer address specified */
else
broad = NULL;
/* Flags. */ /* Flags. */
if (ifa->ifa_flags & IFA_F_SECONDARY) if (ifa->ifa_flags & IFA_F_SECONDARY)
SET_FLAG (flags, ZEBRA_IFA_SECONDARY); SET_FLAG (flags, ZEBRA_IFA_SECONDARY);