p.family = AF_INET;
p.prefixlen = addr->prefixlen;
- if (ifc_pointopoint (ifc))
+ if (if_is_pointopoint (ifp))
p.u.prefix4 = dest->u.prefix4;
else
p.u.prefix4 = addr->u.prefix4;
p.family = AF_INET6;
p.prefixlen = addr->prefixlen;
- if (ifc_pointopoint (ifc))
+ if (if_is_pointopoint (ifp))
p.u.prefix6 = dest->u.prefix6;
else
p.u.prefix6 = addr->u.prefix6;
p.family = AF_INET;
p.prefixlen = addr->prefixlen;
- if (ifc_pointopoint (ifc))
+ if (if_is_pointopoint (ifp))
p.u.prefix4 = dest->u.prefix4;
else
p.u.prefix4 = addr->u.prefix4;
p.family = AF_INET6;
p.prefixlen = addr->prefixlen;
- if (ifc_pointopoint (ifc))
+ if (if_is_pointopoint (ifp))
p.u.prefix6 = dest->u.prefix6;
else
p.u.prefix6 = addr->u.prefix6;
listnode node;
struct prefix addr;
struct prefix best;
- struct prefix peer;
listnode cnode;
struct interface *ifp;
struct prefix *p;
struct connected *c;
struct interface *match;
- int prefixlen;
/* Zero structures - get rid of rubbish from stack */
memset(&addr, 0, sizeof(addr));
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{
c = getdata (cnode);
- p = c->address;
- if (p->family == AF_INET)
+ if (if_is_pointopoint (ifp))
{
- prefixlen = p->prefixlen;
+ p = c->address;
- if (if_is_pointopoint (ifp) ||
- prefixlen >= IPV4_MAX_PREFIXLEN - 1)
+ if (p && p->family == AF_INET)
{
- peer = *c->destination;
- peer.prefixlen = prefixlen;
- p = &peer;
+#ifdef OLD_RIB /* PTP links are conventionally identified
+ by the address of the far end - MAG */
+ if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
+ return ifp;
+#endif
+ p = c->destination;
+ if (p && IPV4_ADDR_SAME (&p->u.prefix4, &src))
+ return ifp;
}
+ }
+ else
+ {
+ p = c->address;
- if (prefix_match (p, &addr) && prefixlen > best.prefixlen)
+ if (p->family == AF_INET)
{
- best = *p;
- match = ifp;
+ if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen)
+ {
+ best = *p;
+ match = ifp;
+ }
}
}
}
/* Lookup first IPv4 address entry. */
LIST_LOOP (ifp->connected, ifc, nn)
{
- if (ifc_pointopoint (ifc))
+ if (if_is_pointopoint (ifp))
p = ifc->destination;
else
p = ifc->address;
* PtP special case: network specified == iface peer addr -> ospf
*/
return (
- ((ifc_pointopoint (co) &&
+ ((if_is_pointopoint (co) &&
IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
|| prefix_match (net, co->address))
? 1 : 0
if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
continue;
- if (ifc_pointopoint (co))
+ if (if_is_pointopoint (co))
addr = co->destination;
else
addr = co->address;
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. */
int
/* The datagram's IPv4 source address should be checked to see
whether the datagram is from a valid neighbor; the source of the
datagram must be on a directly connected network */
- if (if_lookup_address (from->sin_addr) == NULL)
+ if (! if_valid_neighbor (from->sin_addr))
{
zlog_info ("This datagram doesn't came from a valid neighbor: %s",
inet_ntoa (from->sin_addr));
}
/* Check is this packet comming from myself? */
- if (if_lookup_exact_address (from.sin_addr))
+ if (if_check_address (from.sin_addr))
{
if (IS_RIP_DEBUG_PACKET)
zlog_warn ("ignore packet comes from myself");
void rip_zclient_start ();
void rip_zclient_reset ();
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_neighbor_lookup (struct sockaddr_in *);
p.prefixlen = addr->prefixlen;
/* Point-to-point check. */
- if (ifc_pointopoint (ifc) && dest)
+ if (if_is_pointopoint (ifc) && dest)
p.prefix = dest->prefix;
else
p.prefix = addr->prefix;
p.prefixlen = addr->prefixlen;
/* Point-to-point check. */
- if (dest && ifc_pointopoint (ifc))
+ if (dest && if_is_pointopoint (ifc))
p.prefix = dest->prefix;
else
p.prefix = addr->prefix;
p.family = AF_INET6;
p.prefixlen = addr->prefixlen;
- if (ifc_pointopoint (ifc) && dest)
+ if (if_is_pointopoint (ifp) && dest)
{
if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
p.prefix = addr->prefix;
p.family = AF_INET6;
p.prefixlen = addr->prefixlen;
- if (ifc_pointopoint (ifc) && dest)
+ if (if_is_pointopoint (ifp) && dest)
{
if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
p.prefix = addr->prefix;
void *broad = NULL;
u_char flags = 0;
char *label = NULL;
- int peeronly = 0;
ifa = NLMSG_DATA (h);
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)
+
+ if (tb[IFA_ADDRESS] == NULL)
+ tb[IFA_ADDRESS] = tb[IFA_LOCAL];
+
+ if (ifp->flags & IFF_POINTOPOINT)
{
- peeronly = if_is_pointopoint (ifp) ||
- ifa->ifa_prefixlen >= IPV6_MAX_PREFIXLEN - 1;
+ if (tb[IFA_LOCAL])
+ {
+ addr = RTA_DATA (tb[IFA_LOCAL]);
+ 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;
+ }
}
-#endif /* HAVE_IPV6 */
- if (!(tb[IFA_LOCAL] && tb[IFA_ADDRESS]))
+ else
{
- /* FIXME: IPv6 Appears to have only IFA_ADDRESS */
- peeronly = 0;
+ if (tb[IFA_ADDRESS])
+ addr = RTA_DATA (tb[IFA_ADDRESS]);
+ else
+ addr = NULL;
+
+ if (tb[IFA_BROADCAST])
+ broad = RTA_DATA(tb[IFA_BROADCAST]);
+ else
+ broad = NULL;
}
- /* 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. */
if (ifa->ifa_flags & IFA_F_SECONDARY)
SET_FLAG (flags, ZEBRA_IFA_SECONDARY);