[quagga-dev 4433] Re: [quagga-users 7613] Re: FW: Unicast routing with OSPF
paul at clubi.ie
Fri Oct 13 14:02:39 BST 2006
On Wed, 11 Oct 2006, Andrew J. Schorr wrote:
> Thanks for the feedback. And sorry I'm so slow to respond, we just
> moved offices this past Saturday, so everything is still in boxes...
> I agree that this is the ugliest aspect of the patch, and I put
> this in only very reluctantly. If you look in the tree, you will
> see that CONNECTED_ID is used in only 3 places. If I could find a
> way to eliminate those 3 uses, I would be happy to do so. But I do
> believe that all uses of CONNECTED_ID in the patch are consistent
> with the code's current behavior.
> So why is CONNECTED_ID required? The basic idea is that there may
> be some situations in which you want to try to identify a
> particular 'struct connected' by a single associated address. In
> general, this is not possible, but there are nonetheless places in
> the code that call for this.
Ok. So we need a 'best effort'?
> So if you had to try to select an address that you could use for
> identification, what would it be?
> Well, if there's no peer address assigned, then clearly you would
> just choose the local IP address. But if there is a peer address,
> you must choose between the two. In the typical case where the
> peer address is a /32, then you want to use the peer address as the
Right. That's the (near universal (?)) convention (or standard? bet
its mentioned in an RFC somewhere).
> But there's one corner case in which the user has assigned both a
> local and a peer address, and they both live in the same subnet.
> For example, suppose the local address is 192.168.1.1/30, and the
> peer address is 192.168.1.2/30. In principle, there was probably no
> need to specify the peer address in such a case, since the subnet
> assignment makes it clear enough what needs to be done. But
> certainly linux, and I guess probably other platforms as well, do
> not stop you from assigning a peer address in the same subnet.
> And in such a case, I think you most likely want to use 192.168.1.1
> as the identifier, not 192.168.1.2.
Ok. Can that distinction not be handled in CONNECTED_PREFIX though?
> OK, so where are the 3 places in the quagga code that actually require
> such an identifier?
> 1. In ripd/rip_interface.c:rip_interface_multicast_set, we have this
> addr = CONNECTED_ID(connected)->u.prefix4;
> if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
> connected->ifp->ifindex) < 0)
> So which address should we pass to setsockopt_multicast_ipv4? If
> we're lucky, we're on a platform that can use
> connected->ifp->ifindex to identify the interface to the kernel.
> But if we're not on such a platform, we need to try to select the
> address that the kernel would use to identify the interface.
> Would it be OK always to use the peer address if it exists (and
> ignore the strange case where peer and local are in the same
Hmm, no idea. If a peer is specified in the address, then surely that
would always work? I.e. wouldn't relying on local IP to work be the
riskier in such a case?
> Perhaps, I couldn't say without going through all the
> kernel code. In linux, the relevant logic seems to be in
> net/ipv4/fib_frontend.c:ip_dev_find where it calls
> ip_fib_local_table->tb_lookup(address), but it's not obvious to me
> which address we need. But if I conduct the following test:
> bash$ modprobe ip_gre
> bash$ ip tunnel add ptp0 mode gre remote 192.168.50.31 local 192.168.20.93
> bash$ ip link set ptp0 up multicast on
> bash$ ip addr add 192.168.52.1/30 peer 192.168.52.2/30 brd + dev ptp0
> bash$ ip route ls table all | fgrep .52.
> 192.168.52.0/30 dev ptp0 proto kernel scope link src 192.168.52.1
> broadcast 192.168.52.0 dev ptp0 table local proto kernel scope link src 192.168.52.1
> local 192.168.52.1 dev ptp0 table local proto kernel scope host src 192.168.52.1
> broadcast 192.168.52.3 dev ptp0 table local proto kernel scope link src 192.168.52.1
> I get the impression that I need the 192.168.52.1 address in this case
> (since there is no mention of 192.168.52.2 in the routing table), but
> I certainly have doubts and am open to other opinions.
I don't know either. It seems, for the above, either local or peer
would work. We use the local address always though, when we use an
What happens if you configure it such that the peer address does
/not/ fall within the local prefix?
> 2. In ospfd/ospf_snmp.c:ospf_snmp_if_update, it needs an address
> to use to identify the interface. As discussed above, CONNECTED_ID
> is my best guess as to what that address should be (and should give
> consistent behavior with the current code).
For SNMP, the identifier most definitely is the peer. If "Peer is the
identifier" is more than a convention anywhere, SNMP is it :)
(MIB-II, I'll have to look it up, but OSPF RFC2385 refers to it for
PtP link construction in router-LSAs).
> 3. In ospfd/ospfd.c:ospf_network_run. This is the most complicated
> case. But first off, let me again note that using CONNECTED_ID will
> be consistent with the current behavior, since the patch looks like this:
> - if (CONNECTED_POINTOPOINT_HOST(co))
> - addr = co->destination;
> - else
> - addr = co->address;
> + addr = CONNECTED_ID(co);
> So the old code (part of my previous PtP patch) was ugly to begin with. :-)
> So what is the 'addr' variable used for? It's used in one spot, where
> this call is made: ospf_if_is_configured(ospf, &(addr->u.prefix4)).
> We then have to look at ospf_interface.c:ospf_if_is_configured to see
> what it expects as an argument. If oi->type is OSPF_IFTYPE_POINTOPOINT,
> then the CONNECTED_ID address should match fine (since CONNECTED_PREFIX
> should always match CONNECTED_ID). And it seems very unlikely
> that there would be a peer address if the interface type is
> not set to OSPF_IFTYPE_POINTOPOINT, so I don't think we really need
> to worry about the other case very much. So I think we could possibly
> use CONNECTED_PREFIX in this place instead of CONNECTED_ID,
> if you prefer. But it might break some strange case where the
> admin assigned a peer address, but did not set the interface
> type to OSPF_IFTYPE_POINTOPOINT...
We should probably automatically set OSPF_IFTYPE to PtP, unless
configured explicitely otherwise. Isn't this what your patch does
elsewhere in ospfd?
> By the way, this raises the whole question of what the
> ospf_interface 'address' field is supposed to represent.
The local address, always. But yeah, confused.
I guess it might help if, given a struct connected, we listed what
'questions' we might ask of it (the questions being use orientated).
What do we have:
- an abstract identifying number
- the identity address
- the address to use for multicast join/leave operations
(currently using local address, always)
- the local address
(e.g. for constructing a packet)
> Currently, it is set to the struct connected 'address' field, but
> that's arguably not very meaningful for a PtP /32 interface. But
> the code seems to work at the moment, so I didn't muck with this.
> I'm not sure what happen But yes, seems s if you set it to
> CONNECTED_PREFIX instead, but that seems like a more useful value
> to me (in the abstract).
Not when you explicitely want the local address ;). I'm not sure why
it's seperate. Agreed that field likely should be removed.
> Sorry to go on at such length, but this issue is a bit complicated...
> Understood. And I think the current patch's behavior (where
> COMPATIBILITY_MODE is defined by default) should give the same
> 'greedy' behavior that you desire. I still personally think that
> the greedy behavior is inelegant, but I certainly cannot impose my
> view on others...
Well, inelegant or not - that's the behaviour :). It might make the
code more complicated, but gives admins more flexibility in enabling
OSPF (as well as following expectations certain admins may have
acquired from other systems).
Paul Jakma paul at clubi.ie paul at jakma.org Key ID: 64A2FF6A
Maybe you can't buy happiness, but these days you can certainly charge it.
More information about the Quagga-dev