Remi Locherer([email protected]) on 2019.01.10 23:14:15 +0100:
> 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?
ok benno@
> 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;
>