]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/hello.c
Merge pull request #5681 from opensourcerouting/manpage-rename
[mirror_frr.git] / ldpd / hello.c
index 755b25aa85e639944fe13a005bd258304f998d42..d17e80008e0d211557efb497913e1dfc47b0502d 100644 (file)
@@ -214,6 +214,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                    __func__, inet_ntoa(lsr_id));
                return;
        }
+       ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0;
 
        /* implicit transport address */
        if (!(tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR))
@@ -261,19 +262,25 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
                    !((flags & F_HELLO_REQ_TARG))) {
                        tnbr->flags &= ~F_TNBR_DYNAMIC;
-                       tnbr = tnbr_check(tnbr);
+                       tnbr = tnbr_check(leconf, tnbr);
                }
 
                if (!tnbr) {
-                       if (!((flags & F_HELLO_REQ_TARG) &&
-                           ((ldp_af_conf_get(leconf, af))->flags &
-                           F_LDPD_AF_THELLO_ACCEPT)))
+                       struct ldpd_af_conf     *af_conf;
+
+                       if (!(flags & F_HELLO_REQ_TARG))
+                               return;
+                       af_conf = ldp_af_conf_get(leconf, af);
+                       if (!(af_conf->flags & F_LDPD_AF_THELLO_ACCEPT))
+                               return;
+                       if (ldpe_acl_check(af_conf->acl_thello_accept_from, af,
+                           src, (af == AF_INET) ? 32 : 128) != FILTER_PERMIT)
                                return;
 
                        tnbr = tnbr_new(af, src);
                        tnbr->flags |= F_TNBR_DYNAMIC;
                        tnbr_update(tnbr);
-                       LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
+                       RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
                }
 
                source.type = HELLO_TARGETED;
@@ -285,11 +292,21 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                source.link.src_addr = *src;
        }
 
-       adj = adj_find(&source);
+       debug_hello_recv("%s lsr-id %s transport-address %s holdtime %u%s",
+           log_hello_src(&source), inet_ntoa(lsr_id), log_addr(af, &trans_addr),
+            holdtime, (ds_tlv) ? " (dual stack TLV present)" : "");
+
+       adj = adj_find(lsr_id, &source);
+       if (adj && adj->ds_tlv != ds_tlv) {
+               /*
+                * Transient condition, ignore packet and wait until adjacency
+                * times out.
+                */
+               return;
+       }
        nbr = nbr_find_ldpid(lsr_id.s_addr);
 
        /* check dual-stack tlv */
-       ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0;
        if (ds_tlv && trans_pref != leconf->trans_pref) {
                /*
                 * RFC 7552 - Section 6.1.1:
@@ -364,9 +381,10 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                adj = adj_new(lsr_id, &source, &trans_addr);
                if (nbr) {
                        adj->nbr = nbr;
-                       LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
+                       RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
                }
        }
+       adj->ds_tlv = ds_tlv;
 
        /*
         * If the hello adjacency's address-family doesn't match the local
@@ -413,10 +431,6 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
        else
                adj_stop_itimer(adj);
 
-       debug_hello_recv("%s lsr-id %s transport-address %s holdtime %u%s",
-           log_hello_src(&source), inet_ntoa(lsr_id), log_addr(af, &trans_addr),
-            holdtime, (ds_tlv) ? " (dual stack TLV present)" : "");
-
        if (nbr && nbr->state == NBR_STA_PRESENT && !nbr_pending_idtimer(nbr) &&
            nbr_session_active_role(nbr) && !nbr_pending_connect(nbr))
                nbr_establish_connection(nbr);