Hi tech,

in OSPFs external LSAs the type is encoded in the metric field. ospfd and
ospf6d overwrite the type information when "depend on" is used and the
specified interface is down (or in backup state). Below diff fixes this.

The problem was reported on misc by Ior Podlesny:
https://marc.info/?l=openbsd-misc&m=154704895731641&w=2

OK?

Remi



Index: ospfd/ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
retrieving revision 1.103
diff -u -p -r1.103 ospfd.c
--- ospfd/ospfd.c       2 Jan 2019 18:47:59 -0000       1.103
+++ ospfd/ospfd.c       10 Jan 2019 21:08:23 -0000
@@ -564,7 +564,8 @@ ospf_redistribute(struct kroute *kr, u_i
                switch (r->type & ~REDIST_NO) {
                case REDIST_LABEL:
                        if (kr->rtlabel == r->label) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
@@ -579,7 +580,8 @@ ospf_redistribute(struct kroute *kr, u_i
                        if (kr->flags & F_DYNAMIC)
                                continue;
                        if (kr->flags & F_STATIC) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
@@ -589,7 +591,8 @@ ospf_redistribute(struct kroute *kr, u_i
                        if (kr->flags & F_DYNAMIC)
                                continue;
                        if (kr->flags & F_CONNECTED) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
@@ -601,7 +604,7 @@ ospf_redistribute(struct kroute *kr, u_i
                            r->mask.s_addr == INADDR_ANY) {
                                if (is_default) {
                                        *metric = depend_ok ? r->metric :
-                                           MAX_METRIC;
+                                           r->metric | MAX_METRIC;
                                        return (r->type & REDIST_NO ? 0 : 1);
                                } else
                                        return (0);
@@ -610,13 +613,15 @@ ospf_redistribute(struct kroute *kr, u_i
                        if ((kr->prefix.s_addr & r->mask.s_addr) ==
                            (r->addr.s_addr & r->mask.s_addr) &&
                            kr->prefixlen >= mask2prefixlen(r->mask.s_addr)) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
                case REDIST_DEFAULT:
                        if (is_default) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
Index: ospf6d/ospf6d.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.c,v
retrieving revision 1.41
diff -u -p -r1.41 ospf6d.c
--- ospf6d/ospf6d.c     29 Dec 2018 16:04:31 -0000      1.41
+++ ospf6d/ospf6d.c     10 Jan 2019 21:53:10 -0000
@@ -534,7 +534,8 @@ ospf_redistribute(struct kroute *kr, u_i
                switch (r->type & ~REDIST_NO) {
                case REDIST_LABEL:
                        if (kr->rtlabel == r->label) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
@@ -549,7 +550,8 @@ ospf_redistribute(struct kroute *kr, u_i
                        if (kr->flags & F_DYNAMIC)
                                continue;
                        if (kr->flags & F_STATIC) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
@@ -559,7 +561,8 @@ ospf_redistribute(struct kroute *kr, u_i
                        if (kr->flags & F_DYNAMIC)
                                continue;
                        if (kr->flags & F_CONNECTED) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
@@ -571,7 +574,7 @@ ospf_redistribute(struct kroute *kr, u_i
                            r->prefixlen == 0) {
                                if (is_default) {
                                        *metric = depend_ok ? r->metric :
-                                           MAX_METRIC;
+                                           r->metric | MAX_METRIC;
                                        return (r->type & REDIST_NO ? 0 : 1);
                                } else
                                        return (0);
@@ -581,13 +584,15 @@ ospf_redistribute(struct kroute *kr, u_i
                        inet6applymask(&inb, &r->addr, r->prefixlen);
                        if (IN6_ARE_ADDR_EQUAL(&ina, &inb) &&
                            kr->prefixlen >= r->prefixlen) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;
                case REDIST_DEFAULT:
                        if (is_default) {
-                               *metric = depend_ok ? r->metric : MAX_METRIC;
+                               *metric = depend_ok ? r->metric :
+                                   r->metric | MAX_METRIC;
                                return (r->type & REDIST_NO ? 0 : 1);
                        }
                        break;

Reply via email to