I have found a peculiar behaviour in ospfd when the physical link of the
parent carp interface is down. The carp interface net is then announced
with it's regular metric.

An example:
The cable of em2, parent of carp2 (192.168.254.0/23), is unplugged. Here
is what is announced, seen by another machine running bird:

router 192.168.200.4
        distance 10
        network 192.168.200.0/24 metric 10
        stubnet 192.168.202.0/24 metric 65535
        stubnet 192.168.254.0/23 metric 10
        stubnet 195.58.98.144/28 metric 65535
        stubnet 92.33.0.200/30 metric 65535
        stubnet 192.168.253.0/24 metric 10

192.168.254.0/23 is announced with metric 10. All other interfaces in
the same carp group are announced with metric 65535 because the
link-down state of em2 has demoted the carp group, as it should.

This behaviour is cased by the test for the carp state "down" doesn't
check for link state "unknown".

Here is a patch that prevents ospfd from announcing the interface when
the physical interface is down. One could also argue that it should
announce it with metric 65535, as in the carp backup state. But I feel
it is better to not announce it at all since the link down state
prevents us from becoming the master.

Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v
retrieving revision 1.90
diff -u -p -r1.90 ospfe.c
--- ospfe.c     10 Feb 2015 05:24:48 -0000      1.90
+++ ospfe.c     15 May 2015 13:02:40 -0000
@@ -880,7 +880,8 @@ orig_rtr_lsa(struct area *area)
                        if (!(iface->flags & IFF_UP) ||
                            (!LINK_STATE_IS_UP(iface->linkstate) &&
                            !(iface->media_type == IFT_CARP &&
-                           iface->linkstate == LINK_STATE_DOWN)))
+                           iface->linkstate == LINK_STATE_DOWN)) ||
+                           (iface->media_type == IFT_CARP && iface->linkstate 
== LINK_STATE_UNKNOWN))
                                continue;
                        log_debug("orig_rtr_lsa: stub net, "
                            "interface %s", iface->name);


However, this if statement is difficult to understand as it is and
should probably be rewritten, maybe something like this:

Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,vretrieving revision 1.90
diff -u -p -r1.90 ospfe.c
--- ospfe.c     10 Feb 2015 05:24:48 -0000      1.90
+++ ospfe.c     15 May 2015 15:13:38 -0000
@@ -877,11 +877,17 @@ orig_rtr_lsa(struct area *area)
                         *    backup carp interfaces have linkstate down, but
                         *    we still announce them.
                         */
-                       if (!(iface->flags & IFF_UP) ||
-                           (!LINK_STATE_IS_UP(iface->linkstate) &&
-                           !(iface->media_type == IFT_CARP &&
-                           iface->linkstate == LINK_STATE_DOWN)))
-                               continue;
+                       if (!(iface->flags & IFF_UP))
+                         continue; /* admin down */
+                       
+                       if (iface->media_type == IFT_CARP) {
+                         if (iface->linkstate < LINK_STATE_DOWN)
+                           continue; /* physical link down on carp if or 
invaild */
+                       } else {
+                         if (!LINK_STATE_IS_UP(iface->linkstate))
+                           continue; /* UP or UNKNOWN */
+                       }
+
                        log_debug("orig_rtr_lsa: stub net, "
                            "interface %s", iface->name);
 

Also, is the carp kernel code really correct when it leaves the
interface link state as "unknown" when in carp init state?

/Johan Ymerson



Reply via email to