2003-09-29 Paul Jakma <paul@dishone.st>
* zebra/connected.c: revert the 'generic PtP' patch as it causes
far too many problems. People who use FreeSWAN should investigate
native linux ipsec.
* zebra/rt_netlink.c: ditto
* lib/if.c: ditto
* ripd/ripd.h: ditto
* ripd/ripd.c: ditto
* ripd/rip_interface.c: ditto
* ospfd/ospfd.c: ditto
* ospfd/ospf_snmp.c: ditto
* bgpd/bgp_nexthop.c: ditto
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 77b024e..3b91373 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -663,7 +663,7 @@
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;
@@ -694,7 +694,7 @@
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;
@@ -748,7 +748,7 @@
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;
@@ -779,7 +779,7 @@
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;
diff --git a/lib/if.c b/lib/if.c
index 68e6e4a..524869b 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -245,13 +245,11 @@
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));
@@ -270,24 +268,34 @@
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;
+ }
}
}
}
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 41955ba..e3d01fb 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -1440,7 +1440,7 @@
/* 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;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index aeae8e1..77bb6a4 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -714,7 +714,7 @@
* 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
@@ -756,7 +756,7 @@
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;
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index b472522..2668e7d 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -396,6 +396,106 @@
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
diff --git a/ripd/ripd.c b/ripd/ripd.c
index d2a6b4d..68f49ac 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -1017,7 +1017,7 @@
/* 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));
@@ -1602,7 +1602,7 @@
}
/* 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");
diff --git a/ripd/ripd.h b/ripd/ripd.h
index c414c76..dc2f64d 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -374,6 +374,8 @@
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 *);
diff --git a/zebra/connected.c b/zebra/connected.c
index 280e423..1d19258 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -69,7 +69,7 @@
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;
@@ -163,7 +163,7 @@
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;
@@ -250,7 +250,7 @@
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;
@@ -343,7 +343,7 @@
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;
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a2efa17..02cae6e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -487,7 +487,6 @@
void *broad = NULL;
u_char flags = 0;
char *label = NULL;
- int peeronly = 0;
ifa = NLMSG_DATA (h);
@@ -539,40 +538,41 @@
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);