Hi,
I am attaching a patch to enhance quagga support for point-to-point
interfaces. Based on my (perhaps incomplete) understanding of
the current code, it is mostly designed to support PtP connections
where the local and peer addresses are borrowed from other interfaces
and specified with a /32 netmask. In the case where one wants to
have a specifically assigned subnet (typically /30) for a PtP link
(not sharing IP addresses with other interfaces), quagga does not
seem to work. Under linux using the iproute2 tools, it is certainly
possible to assign a subnet to a PtP link, and it is optional whether
to specify a peer address in such a case. This patch gets quagga
to support that scenario.
The zebra daemon allows for the possibility of a PtP interface
where the local address is present, but not the peer address.
However, in zebra/zserv.c:zsend_interface_address_add(), the code
translates a NULL destination address pointer into a 0.0.0.0 address.
So the child daemons (e.g. ripd, or ospfd) never receive the
destination address as a NULL pointer, instead they get 0.0.0.0.
So my patch fixes that problem.
Also, in zebra/rt_netlink.c:netlink_interface_addr(), I had to add a
memcmp to ignore the peer address when it's the same as the
local address (this is copied from iproute2/ip/ipaddress.c:print_addrinfo().
Without that patch, zebra thinks that the local address is also the peer
address in the situation where a peer address was never assigned.
Other than that, it's a question of patching the lib and daemon directories
to stop assuming that the connected->destination pointer is non-NULL.
This involves some minor patches to ripd and bgpd (not tested),
and some more significant patches to ospfd.
In general, my patches get the code to behave the same as it
did before if the connected->destination address is present and the
prefixlen is IPV4_MAX_PREFIXLEN (32). If the destination address
is missing, or the prefixlen is not 32, then it is assumed that a
specific subnet has been dedicated to the PtP link, and the PtP
interface is not identified by the peer address.
Most of the changes to ospfd were to add more debugging statements so
that I could see what was going on. The signicant changes were in
ospf_interface.c to define a new function ospf_if_is_connected,
and then to ospf_spf.c:ospf_nexthop_calculation() to call the new
function instead of ospf_if_is_configured(). And I patched
ospf_lsa.c:lsa_link_ptop_set() to ignore the destination address
if the prefixlen is not 32.
So with this patch, one now has the option of configuring the PtP
interface with a dedicated subnet, just as is possible with Cisco IOS.
In that scenario, one no longer has the strange routes through the
remote router to the local PtP interface.
This patch was developed against quagga-0.96.4 under Linux 2.4.22.
I then forward-ported it to apply against this morning's CVS snapshot.
I have not tested with the CVS code, but it does compile.
I hope somebody finds this patch helpful, and it would be great if it
could be integrated into CVS. I am very interested in any comments you
may have, positive or negative; I know this is very desirable functionality
for our site, and I hope others are interested.
-Andy
I am attaching a patch to enhance quagga support for point-to-point
interfaces. Based on my (perhaps incomplete) understanding of
the current code, it is mostly designed to support PtP connections
where the local and peer addresses are borrowed from other interfaces
and specified with a /32 netmask. In the case where one wants to
have a specifically assigned subnet (typically /30) for a PtP link
(not sharing IP addresses with other interfaces), quagga does not
seem to work. Under linux using the iproute2 tools, it is certainly
possible to assign a subnet to a PtP link, and it is optional whether
to specify a peer address in such a case. This patch gets quagga
to support that scenario.
The zebra daemon allows for the possibility of a PtP interface
where the local address is present, but not the peer address.
However, in zebra/zserv.c:zsend_interface_address_add(), the code
translates a NULL destination address pointer into a 0.0.0.0 address.
So the child daemons (e.g. ripd, or ospfd) never receive the
destination address as a NULL pointer, instead they get 0.0.0.0.
So my patch fixes that problem.
Also, in zebra/rt_netlink.c:netlink_interface_addr(), I had to add a
memcmp to ignore the peer address when it's the same as the
local address (this is copied from iproute2/ip/ipaddress.c:print_addrinfo().
Without that patch, zebra thinks that the local address is also the peer
address in the situation where a peer address was never assigned.
Other than that, it's a question of patching the lib and daemon directories
to stop assuming that the connected->destination pointer is non-NULL.
This involves some minor patches to ripd and bgpd (not tested),
and some more significant patches to ospfd.
In general, my patches get the code to behave the same as it
did before if the connected->destination address is present and the
prefixlen is IPV4_MAX_PREFIXLEN (32). If the destination address
is missing, or the prefixlen is not 32, then it is assumed that a
specific subnet has been dedicated to the PtP link, and the PtP
interface is not identified by the peer address.
Most of the changes to ospfd were to add more debugging statements so
that I could see what was going on. The signicant changes were in
ospf_interface.c to define a new function ospf_if_is_connected,
and then to ospf_spf.c:ospf_nexthop_calculation() to call the new
function instead of ospf_if_is_configured(). And I patched
ospf_lsa.c:lsa_link_ptop_set() to ignore the destination address
if the prefixlen is not 32.
So with this patch, one now has the option of configuring the PtP
interface with a dedicated subnet, just as is possible with Cisco IOS.
In that scenario, one no longer has the strange routes through the
remote router to the local PtP interface.
This patch was developed against quagga-0.96.4 under Linux 2.4.22.
I then forward-ported it to apply against this morning's CVS snapshot.
I have not tested with the CVS code, but it does compile.
I hope somebody finds this patch helpful, and it would be great if it
could be integrated into CVS. I am very interested in any comments you
may have, positive or negative; I know this is very desirable functionality
for our site, and I hope others are interested.
-Andy