]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/l2vpn.c
zebra: Refactor kernel_rtm to be a bit smarter about how it handles options
[mirror_frr.git] / ldpd / l2vpn.c
index afb9528d8099d756e30488b92a11bf41ffad6dc8..7f2e396a7f5c849f9e41bf51133eac3bbcd076a0 100644 (file)
 #include "log.h"
 
 static void             l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
-static __inline int     l2vpn_compare(struct l2vpn *, struct l2vpn *);
-static __inline int     l2vpn_if_compare(struct l2vpn_if *, struct l2vpn_if *);
-static __inline int     l2vpn_pw_compare(struct l2vpn_pw *, struct l2vpn_pw *);
+static __inline int     l2vpn_compare(const struct l2vpn *, const struct l2vpn *);
+static __inline int     l2vpn_if_compare(const struct l2vpn_if *, const struct l2vpn_if *);
+static __inline int     l2vpn_pw_compare(const struct l2vpn_pw *, const struct l2vpn_pw *);
 
 RB_GENERATE(l2vpn_head, l2vpn, entry, l2vpn_compare)
 RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare)
 RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare)
 
 static __inline int
-l2vpn_compare(struct l2vpn *a, struct l2vpn *b)
+l2vpn_compare(const struct l2vpn *a, const struct l2vpn *b)
 {
        return (strcmp(a->name, b->name));
 }
@@ -55,9 +55,9 @@ l2vpn_new(const char *name)
        l2vpn->mtu = DEFAULT_L2VPN_MTU;
        l2vpn->pw_type = DEFAULT_PW_TYPE;
 
-       RB_INIT(&l2vpn->if_tree);
-       RB_INIT(&l2vpn->pw_tree);
-       RB_INIT(&l2vpn->pw_inactive_tree);
+       RB_INIT(l2vpn_if_head, &l2vpn->if_tree);
+       RB_INIT(l2vpn_pw_head, &l2vpn->pw_tree);
+       RB_INIT(l2vpn_pw_head, &l2vpn->pw_inactive_tree);
 
        return (l2vpn);
 }
@@ -76,15 +76,21 @@ l2vpn_del(struct l2vpn *l2vpn)
        struct l2vpn_if         *lif;
        struct l2vpn_pw         *pw;
 
-       while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
+       while (!RB_EMPTY(l2vpn_if_head, &l2vpn->if_tree)) {
+               lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree);
+
                RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
                free(lif);
        }
-       while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
+       while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_tree)) {
+               pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree);
+
                RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
                free(pw);
        }
-       while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
+       while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_inactive_tree)) {
+               pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_inactive_tree);
+
                RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
                free(pw);
        }
@@ -111,9 +117,9 @@ l2vpn_exit(struct l2vpn *l2vpn)
 }
 
 static __inline int
-l2vpn_if_compare(struct l2vpn_if *a, struct l2vpn_if *b)
+l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b)
 {
-       return (strcmp(a->ifname, b->ifname));
+       return if_cmp_name_func(a->ifname, b->ifname);
 }
 
 struct l2vpn_if *
@@ -174,9 +180,9 @@ l2vpn_if_update(struct l2vpn_if *lif)
 }
 
 static __inline int
-l2vpn_pw_compare(struct l2vpn_pw *a, struct l2vpn_pw *b)
+l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b)
 {
-       return (strcmp(a->ifname, b->ifname));
+       return if_cmp_name_func(a->ifname, b->ifname);
 }
 
 struct l2vpn_pw *
@@ -238,13 +244,13 @@ l2vpn_pw_init(struct l2vpn_pw *pw)
 
        l2vpn_pw_reset(pw);
 
+       pw2zpw(pw, &zpw);
+       lde_imsg_compose_parent(IMSG_KPW_ADD, 0, &zpw, sizeof(zpw));
+
        l2vpn_pw_fec(pw, &fec);
        lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
            0, (void *)pw);
        lde_kernel_update(&fec);
-
-       pw2zpw(pw, &zpw);
-       lde_imsg_compose_parent(IMSG_KPW_ADD, 0, &zpw, sizeof(zpw));
 }
 
 void
@@ -294,17 +300,26 @@ int
 l2vpn_pw_ok(struct l2vpn_pw *pw, struct fec_nh *fnh)
 {
        /* check for a remote label */
-       if (fnh->remote_label == NO_LABEL)
+       if (fnh->remote_label == NO_LABEL) {
+               log_warnx("%s: pseudowire %s: no remote label", __func__,
+                         pw->ifname);
                return (0);
+       }
 
        /* MTUs must match */
-       if (pw->l2vpn->mtu != pw->remote_mtu)
+       if (pw->l2vpn->mtu != pw->remote_mtu) {
+               log_warnx("%s: pseudowire %s: MTU mismatch detected", __func__,
+                         pw->ifname);
                return (0);
+       }
 
        /* check pw status if applicable */
        if ((pw->flags & F_PW_STATUSTLV) &&
-           pw->remote_status != PW_FORWARDING)
+           pw->remote_status != PW_FORWARDING) {
+               log_warnx("%s: pseudowire %s: remote end is down", __func__,
+                         pw->ifname);
                return (0);
+       }
 
        return (1);
 }
@@ -549,7 +564,8 @@ l2vpn_pw_ctl(pid_t pid)
                            sizeof(pwctl.ifname));
                        pwctl.pwid = pw->pwid;
                        pwctl.lsr_id = pw->lsr_id;
-                       if (pw->local_status == PW_FORWARDING &&
+                       if (pw->enabled &&
+                           pw->local_status == PW_FORWARDING &&
                            pw->remote_status == PW_FORWARDING)
                                pwctl.status = 1;
 
@@ -573,7 +589,7 @@ l2vpn_binding_ctl(pid_t pid)
 
                fn = (struct fec_node *)f;
                if (fn->local_label == NO_LABEL &&
-                   RB_EMPTY(&fn->downstream))
+                   RB_EMPTY(lde_map_head, &fn->downstream))
                        continue;
 
                memset(&pwctl, 0, sizeof(pwctl));