fix "depend on" when carp interface goes from MASTER into state INIT
authorbenno <benno@openbsd.org>
Mon, 29 May 2017 14:22:51 +0000 (14:22 +0000)
committerbenno <benno@openbsd.org>
Mon, 29 May 2017 14:22:51 +0000 (14:22 +0000)
aka UNKNOWN.
ok claudio@ phessler@ and henning helped along too

usr.sbin/bgpd/session.c

index bbe20d1..61cd8dc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: session.c,v 1.363 2017/05/28 20:10:59 claudio Exp $ */
+/*     $OpenBSD: session.c,v 1.364 2017/05/29 14:22:51 benno Exp $ */
 
 /*
  * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -95,6 +95,7 @@ void  session_dispatch_imsg(struct imsgbuf *, int, u_int *);
 void   session_up(struct peer *);
 void   session_down(struct peer *);
 void   session_demote(struct peer *, int);
+int    session_link_state_is_up(int, int, int);
 
 int             la_cmp(struct listen_addr *, struct listen_addr *);
 struct peer    *getpeerbyip(struct sockaddr *);
@@ -2808,8 +2809,8 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
                            sizeof(struct kif))
                                fatalx("IFINFO imsg with wrong len");
                        kif = imsg.data;
-                       depend_ok = (kif->flags & IFF_UP) &&
-                           LINK_STATE_IS_UP(kif->link_state);
+                       depend_ok = session_link_state_is_up(kif->flags,
+                           kif->if_type, kif->link_state);
 
                        for (p = peers; p != NULL; p = p->next)
                                if (!strcmp(p->conf.if_depend, kif->ifname)) {
@@ -3276,3 +3277,22 @@ session_stop(struct peer *peer, u_int8_t subcode)
        }
        bgp_fsm(peer, EVNT_STOP);
 }
+
+/*
+ * return 1 when the interface is up
+ * and the link state is up or unknwown
+ * except when this is a carp interface, then
+ * return 1 only when link state is up
+ */
+int
+session_link_state_is_up(int flags, int type, int link_state)
+{
+       if (!(flags & IFF_UP))
+               return (0);
+
+       if (type == IFT_CARP &&
+           link_state == LINK_STATE_UNKNOWN)
+               return (0);
+
+       return LINK_STATE_IS_UP(link_state);
+}