]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #5246 from sworleys/README-Frr-Chicken
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Wed, 30 Oct 2019 07:08:04 +0000 (09:08 +0200)
committerGitHub <noreply@github.com>
Wed, 30 Oct 2019 07:08:04 +0000 (09:08 +0200)
Add FRR Icon to README

15 files changed:
bfdd/bfd.c
bfdd/bfd.h
bfdd/bfdd_northbound.c
bfdd/control.c
bfdd/ptm_adapter.c
bgpd/bgp_bfd.c
isisd/isis_bfd.c
lib/bfd.c
lib/bfd.h
lib/if.c
lib/if.h
ospf6d/ospf6_bfd.c
ospfd/ospf_bfd.c
pimd/pim_bfd.c
vrrpd/vrrp.c

index d2b60100e18e498d919a5018c4476074505bad81..6e956aa92957787fd5f27531bf29f4f480283c79 100644 (file)
@@ -49,6 +49,8 @@ static void bs_admin_down_handler(struct bfd_session *bs, int nstate);
 static void bs_down_handler(struct bfd_session *bs, int nstate);
 static void bs_init_handler(struct bfd_session *bs, int nstate);
 static void bs_up_handler(struct bfd_session *bs, int nstate);
+static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
+                                           uint8_t diag);
 
 /* Zeroed array with the size of an IPv6 address. */
 struct in6_addr zero_addr;
@@ -312,7 +314,7 @@ void ptm_bfd_sess_up(struct bfd_session *bfd)
        /* Start sending control packets with poll bit immediately. */
        ptm_bfd_snd(bfd, 0);
 
-       control_notify(bfd);
+       control_notify(bfd, bfd->ses_state);
 
        if (old_state != bfd->ses_state) {
                bfd->stats.session_up++;
@@ -347,7 +349,7 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag)
 
        /* only signal clients when going from up->down state */
        if (old_state == PTM_BFD_UP)
-               control_notify(bfd);
+               control_notify(bfd, PTM_BFD_DOWN);
 
        /* Stop echo packet transmission if they are active */
        if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
@@ -582,7 +584,7 @@ skip_echo:
 
                /* Change and notify state change. */
                bs->ses_state = PTM_BFD_ADM_DOWN;
-               control_notify(bs);
+               control_notify(bs, bs->ses_state);
 
                /* Don't try to send packets with a disabled session. */
                if (bs->sock != -1)
@@ -596,7 +598,7 @@ skip_echo:
 
                /* Change and notify state change. */
                bs->ses_state = PTM_BFD_DOWN;
-               control_notify(bs);
+               control_notify(bs, bs->ses_state);
 
                /* Enable all timers. */
                bfd_recvtimer_update(bs);
@@ -868,10 +870,46 @@ static void bs_init_handler(struct bfd_session *bs, int nstate)
        }
 }
 
+static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
+                                           uint8_t diag)
+{
+       int old_state = bfd->ses_state;
+
+       bfd->local_diag = diag;
+       bfd->discrs.remote_discr = 0;
+       bfd->ses_state = PTM_BFD_DOWN;
+       bfd->polling = 0;
+       bfd->demand_mode = 0;
+       monotime(&bfd->downtime);
+
+       /* Slow down the control packets, the connection is down. */
+       bs_set_slow_timers(bfd);
+
+       /* only signal clients when going from up->down state */
+       if (old_state == PTM_BFD_UP)
+               control_notify(bfd, PTM_BFD_ADM_DOWN);
+
+       /* Stop echo packet transmission if they are active */
+       if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
+               ptm_bfd_echo_stop(bfd);
+
+       if (old_state != bfd->ses_state) {
+               bfd->stats.session_down++;
+
+               log_info("state-change: [%s] %s -> %s reason:%s",
+                       bs_to_string(bfd), state_list[old_state].str,
+                       state_list[bfd->ses_state].str,
+                       get_diag_str(bfd->local_diag));
+       }
+}
+
 static void bs_up_handler(struct bfd_session *bs, int nstate)
 {
        switch (nstate) {
        case PTM_BFD_ADM_DOWN:
+               bs_neighbour_admin_down_handler(bs, BD_ADMIN_DOWN);
+               break;
+
        case PTM_BFD_DOWN:
                /* Peer lost or asked to shutdown connection. */
                ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
index a9c8bd183a844ede1ef35afe59c7b05e13679360..815b0aec2e2b3c132291646446394b192116dcdb 100644 (file)
@@ -365,7 +365,7 @@ TAILQ_HEAD(bcslist, bfd_control_socket);
 
 int control_init(const char *path);
 void control_shutdown(void);
-int control_notify(struct bfd_session *bs);
+int control_notify(struct bfd_session *bs, uint8_t notify_state);
 int control_notify_config(const char *op, struct bfd_session *bs);
 int control_accept(struct thread *t);
 
@@ -628,7 +628,7 @@ void bfdd_sessions_enable_vrf(struct vrf *vrf);
 void bfdd_sessions_disable_vrf(struct vrf *vrf);
 void bfd_session_update_vrf_name(struct bfd_session *bs, struct vrf *vrf);
 
-int ptm_bfd_notify(struct bfd_session *bs);
+int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state);
 
 
 /*
index 975fc7b31f6467fe61815d967fbcb55dbbd7b59d..edbd406918e5ed2b5e0a1fcaf427861f8b61071b 100644 (file)
@@ -431,7 +431,7 @@ static int bfdd_bfd_sessions_single_hop_administrative_down_modify(
 
                /* Change and notify state change. */
                bs->ses_state = PTM_BFD_DOWN;
-               control_notify(bs);
+               control_notify(bs, bs->ses_state);
 
                /* Enable all timers. */
                bfd_recvtimer_update(bs);
@@ -454,7 +454,7 @@ static int bfdd_bfd_sessions_single_hop_administrative_down_modify(
 
                /* Change and notify state change. */
                bs->ses_state = PTM_BFD_ADM_DOWN;
-               control_notify(bs);
+               control_notify(bs, bs->ses_state);
 
                ptm_bfd_snd(bs, 0);
        }
index c308d647d83e36c5084babc7e362dd6de02d4c7c..5c5421c041057bba33cdea79b924b6b525225b93 100644 (file)
@@ -774,13 +774,13 @@ static void _control_notify(struct bfd_control_socket *bcs,
        control_queue_enqueue(bcs, bcm);
 }
 
-int control_notify(struct bfd_session *bs)
+int control_notify(struct bfd_session *bs, uint8_t notify_state)
 {
        struct bfd_control_socket *bcs;
        struct bfd_notify_peer *bnp;
 
        /* Notify zebra listeners as well. */
-       ptm_bfd_notify(bs);
+       ptm_bfd_notify(bs, notify_state);
 
        /*
         * PERFORMANCE: reuse the bfd_control_msg allocated data for
index df48bc2af0fd6cfa64c1b9049f144baf94186c7b..dcca70b796f07751debf14f17b1eb2dfd998404f 100644 (file)
@@ -153,7 +153,7 @@ static int _ptm_msg_address(struct stream *msg, int family, const void *addr)
        return 0;
 }
 
-int ptm_bfd_notify(struct bfd_session *bs)
+int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state)
 {
        struct stream *msg;
 
@@ -204,12 +204,15 @@ int ptm_bfd_notify(struct bfd_session *bs)
        _ptm_msg_address(msg, bs->key.family, &bs->key.peer);
 
        /* BFD status */
-       switch (bs->ses_state) {
+       switch (notify_state) {
        case PTM_BFD_UP:
                stream_putl(msg, BFD_STATUS_UP);
                break;
 
        case PTM_BFD_ADM_DOWN:
+               stream_putl(msg, BFD_STATUS_ADMIN_DOWN);
+               break;
+
        case PTM_BFD_DOWN:
        case PTM_BFD_INIT:
                stream_putl(msg, BFD_STATUS_DOWN);
@@ -432,7 +435,7 @@ static void bfdd_dest_register(struct stream *msg, vrf_id_t vrf_id)
                return;
        }
 
-       ptm_bfd_notify(bs);
+       ptm_bfd_notify(bs, bs->ses_state);
 }
 
 static void bfdd_dest_deregister(struct stream *msg, vrf_id_t vrf_id)
@@ -461,6 +464,10 @@ static void bfdd_dest_deregister(struct stream *msg, vrf_id_t vrf_id)
        if (bs->refcount ||
            BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
                return;
+
+       bs->ses_state = PTM_BFD_ADM_DOWN;
+       ptm_bfd_snd(bs, 0);
+
        ptm_bfd_sess_del(&bpc);
 }
 
index 57fef8e9139f5cc467dd35e26713b8379a1bc31f..0ed6057eac1b795bcb46170b49cd1308d61a2ff9 100644 (file)
@@ -282,7 +282,8 @@ static void bgp_bfd_peer_status_update(struct peer *peer, int status,
                return;
 
        old_status = bfd_info->status;
-       bfd_info->status = status;
+       BFD_SET_CLIENT_STATUS(bfd_info->status, status);
+
        bfd_info->last_update = bgp_clock();
 
        if (status != old_status) {
index 8fc7997d79f085cc46754355ebb7436a8d9bf3d3..cf4b841798748959659b4bad758c7663e4d685b9 100644 (file)
@@ -118,7 +118,8 @@ static void bfd_adj_event(struct isis_adjacency *adj, struct prefix *dst,
 
        int old_status = adj->bfd_session->status;
 
-       adj->bfd_session->status = new_status;
+       BFD_SET_CLIENT_STATUS(adj->bfd_session->status, new_status);
+
        if (old_status == new_status)
                return;
 
index 00dbd1b3d1ef1f160c4b737838b9d596ae8b8511..ffb3cbc1f86f044da7a9cf4d0b1d0131561a3b6f 100644 (file)
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -315,6 +315,8 @@ const char *bfd_get_status_str(int status)
                return "Down";
        case BFD_STATUS_UP:
                return "Up";
+       case BFD_STATUS_ADMIN_DOWN:
+               return "Admin Down";
        case BFD_STATUS_UNKNOWN:
        default:
                return "Unknown";
index e4781f4eaf9e45cbe664dd029620f14c444fbe47..7f5d111504639ac51cac1d5765f416de0779db88 100644 (file)
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -51,9 +51,17 @@ struct bfd_gbl {
 #define BFD_FLAG_BFD_CBIT_ON (1 << 3) /* Peer registered with CBIT set to on */
 #define BFD_FLAG_BFD_CHECK_CONTROLPLANE (1 << 4) /* BFD and controlplane daemon are linked */
 
-#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
-#define BFD_STATUS_DOWN    (1 << 1) /* BFD session status is down */
-#define BFD_STATUS_UP      (1 << 2) /* BFD session status is up */
+#define BFD_STATUS_UNKNOWN    (1 << 0) /* BFD session status never received */
+#define BFD_STATUS_DOWN       (1 << 1) /* BFD session status is down */
+#define BFD_STATUS_UP         (1 << 2) /* BFD session status is up */
+#define BFD_STATUS_ADMIN_DOWN (1 << 3) /* BFD session is admin down */
+
+#define BFD_SET_CLIENT_STATUS(current_status, new_status)                \
+       do {                                                              \
+               (current_status) =                                        \
+                       (((new_status) == BFD_STATUS_ADMIN_DOWN) ?        \
+                                         BFD_STATUS_DOWN : (new_status));\
+       } while (0)
 
 enum bfd_sess_type {
        BFD_TYPE_NOT_CONFIGURED,
index 594961d763ceaa6e630f5714fec98f961af66914..7c3606bbbf9b617187992b2749460ef5f5d6da5f 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -959,6 +959,20 @@ static int connected_same_prefix(struct prefix *p1, struct prefix *p2)
        return 0;
 }
 
+/* count the number of connected addresses that are in the given family */
+unsigned int connected_count_by_family(struct interface *ifp, int family)
+{
+       struct listnode *cnode;
+       struct connected *connected;
+       unsigned int cnt = 0;
+
+       for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected))
+               if (connected->address->family == family)
+                       cnt++;
+
+       return cnt;
+}
+
 struct connected *connected_lookup_prefix_exact(struct interface *ifp,
                                                struct prefix *p)
 {
index 1ee6561e8d481b5900e1fcf0c1575bc80d2b9724..632229093735478db83605bfe2a93f3ed3d3e5db 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -553,6 +553,7 @@ extern struct connected *connected_lookup_prefix(struct interface *,
                                                 struct prefix *);
 extern struct connected *connected_lookup_prefix_exact(struct interface *,
                                                       struct prefix *);
+extern unsigned int connected_count_by_family(struct interface *, int family);
 extern struct nbr_connected *nbr_connected_new(void);
 extern void nbr_connected_free(struct nbr_connected *);
 struct nbr_connected *nbr_connected_check(struct interface *, struct prefix *);
index f0500601b09054851788896bfa10e4eeef989f53..4e7a0050aa26227776ed97ee4043b8f78b341c44 100644 (file)
@@ -236,7 +236,7 @@ static int ospf6_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
                        continue;
 
                old_status = bfd_info->status;
-               bfd_info->status = status;
+               BFD_SET_CLIENT_STATUS(bfd_info->status, status);
                monotime(&tv);
                bfd_info->last_update = tv.tv_sec;
 
index a17975270af957fd8603dad512e163b2b9212de5..73802ce13e83aaff8f97f9e299a449715b99da36 100644 (file)
@@ -240,7 +240,7 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
                        continue;
 
                old_status = bfd_info->status;
-               bfd_info->status = status;
+               BFD_SET_CLIENT_STATUS(bfd_info->status, status);
                monotime(&tv);
                bfd_info->last_update = tv.tv_sec;
 
index 87d0f9fa22d10bde25eaaf07a12b207f0ff0a5e7..01a7980858f6d660ebea49d0e0d88e01d3eb93e3 100644 (file)
@@ -270,7 +270,7 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
                        continue;
                }
                old_status = bfd_info->status;
-               bfd_info->status = status;
+               BFD_SET_CLIENT_STATUS(bfd_info->status, status);
                monotime(&tv);
                bfd_info->last_update = tv.tv_sec;
 
index 54089b3612b819343aa414a118207e9ae5cba5b8..df2376c4739205f7d4d658bb7eca8bdc394b4637 100644 (file)
@@ -298,7 +298,7 @@ void vrrp_check_start(struct vrrp_vrouter *vr)
        start = start && if_is_operative(vr->ifp);
 #endif
        /* Parent interface must have at least one v4 */
-       start = start && vr->ifp->connected->count > 1;
+       start = start && connected_count_by_family(vr->ifp, AF_INET) > 0;
        whynot = (!start && !whynot) ? "No primary IPv4 address" : whynot;
        /* Must have a macvlan interface */
        start = start && (r->mvl_ifp != NULL);
@@ -341,17 +341,17 @@ void vrrp_check_start(struct vrrp_vrouter *vr)
        /* Macvlan interface must have a link local */
        start = start && connected_get_linklocal(r->mvl_ifp);
        whynot =
-               (!start && !whynot) ? "No link local address configured" : NULL;
+               (!start && !whynot) ? "No link local address configured" : whynot;
        /* Macvlan interface must have a v6 IP besides the link local */
-       start = start && (r->mvl_ifp->connected->count >= 2);
+       start = start && (connected_count_by_family(r->mvl_ifp, AF_INET6) > 1);
        whynot = (!start && !whynot)
-                        ? "No Virtual IP configured on macvlan device"
-                        : NULL;
+                        ? "No Virtual IPv6 address configured on macvlan device"
+                        : whynot;
 #endif
        /* Must have at least one VIP configured */
        start = start && r->addrs->count > 0;
        whynot =
-               (!start && !whynot) ? "No Virtual IP address configured" : NULL;
+               (!start && !whynot) ? "No Virtual IP address configured" : whynot;
        if (start)
                vrrp_event(r, VRRP_EVENT_STARTUP);
        else if (whynot)