On Sat, Nov 16, 2019 at 06:58:35AM +0100, Claudio Jeker wrote:
> On Fri, Nov 15, 2019 at 06:06:42PM +0100, Remi Locherer wrote:
> > On Mon, Nov 04, 2019 at 02:01:57PM +0200, Kapetanakis Giannis wrote:
> > > On 25/10/2019 13:57, Remi Locherer wrote:
> > > > Hi tech@,
> > > >
> > > > earlier this year I sent a diff that allowed to change an interface
> > > > from broadcast to point-to-point.
> > > >
> > > > https://marc.info/?l=openbsd-tech&m=156132923203704&w=2
> > > >
> > > > It turned out that this was not sufficient. It made the adjacency
> > > > come up in p2p mode (no selection of DR or BDR) but didn't set a valid
> > > > next hop for routes learned over this p2p link. Actually the next hop 
> > > > was
> > > > 0.0.0.0 which was never installed into the routing table.
> > > >
> > > > This is because for P2P interfaces the neighbor address is not taken 
> > > > from
> > > > the received hello but from the "destination" parameter configured on 
> > > > the
> > > > interface. Since this is not set on a broadcast interface the address is
> > > > 0.0.0.0.
> > > >
> > > > My new diff changes this. Now also for P2P links the IP address of the
> > > > neighbor is taken from the hello packets (src address). This on it's own
> > > > would make it simpler to interfere with the routing from remote. One 
> > > > could
> > > > send unicast ospf hello messages and potentially disrupt the routing 
> > > > setup.
> > > > I believe I mitigated this with an additional check I committed in 
> > > > August:
> > > > only hello messages sent to the multicast address are now processed.
> > > >
> > > > The config looks like this:
> > > >
> > > > area 0.0.0.0 {
> > > >         interface em0 {
> > > >                 type p2p
> > > >         }
> > > > }
> > > >
> > > > It would be nice to get test reports for this new feature (check the fib
> > > > and routing table!) and also test reports with real p2p2 interfaces (gif
> > > > or gre).
> > > >
> > > > Of course OKs are also welcome. ;-)
> > > >
> > > > Remi
> > > 
> > > 
> > > Hi,
> > > 
> > > From first test seems to work :)
> > > 
> > > looking forward test it for IPv6 as well
> > > 
> > > thanks
> > > 
> > > Giannis
> > 
> > 
> > Anyone willing to OK this?
> 
> See inline.
> 

[...]

> 
> Another option is to just add this ospfe_imsg_compose_rde() to the two
> places where the addr is updated.

Right, that is actually simpler.

> 
> > +
> > +   return (0);
> >  }
> >  
> >  struct nbr *
> > Index: ospfd.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
> > retrieving revision 1.108
> > diff -u -p -r1.108 ospfd.c
> > --- ospfd.c 16 May 2019 05:49:22 -0000      1.108
> > +++ ospfd.c 23 Jun 2019 21:06:44 -0000
> > @@ -911,6 +911,22 @@ merge_interfaces(struct area *a, struct 
> >                             if_fsm(i, IF_EVT_UP);
> >             }
> >  
> > +           if (i->p2p != xi->p2p) {
> > +                   /* re-add interface to enable or disable DR election */
> > +                   if (ospfd_process == PROC_OSPF_ENGINE)
> > +                           if_fsm(i, IF_EVT_DOWN);
> > +                   else if (ospfd_process == PROC_RDE_ENGINE)
> > +                           rde_nbr_iface_del(i);
> > +                   LIST_REMOVE(i, entry);
> > +                   if_del(i);
> > +                   LIST_REMOVE(xi, entry);
> > +                   LIST_INSERT_HEAD(&a->iface_list, xi, entry);
> > +                   xi->area = a;
> > +                   if (ospfd_process == PROC_OSPF_ENGINE)
> > +                           xi->state = IF_STA_NEW;
> > +                   continue;
> > +           }
> 
> This is one big hammer. Would be nice to be a bit softer, also should this
> code be before
>               log_debug("merge_interfaces: proc %d area %s merging "
>                   "interface %s", ospfd_process, inet_ntoa(a->id), i->name);
> 
> Since it re-adds an interface. If so it should also have its own
> log_debug(). At least I think it makes little sense to merge most of the
> interface to just remove it and re-add it.

I somehow added this with my first attempt and didn't re-evaluate. It turns
out that a restart is actually sufficient.

> 
> > +
> >             strlcpy(i->dependon, xi->dependon,
> >                     sizeof(i->dependon));
> >             i->depend_ok = xi->depend_ok;
> 
> Unrelated but I feel this code should be moved up before
>               if (i->passive != xi->passive) {
>                       ...
>               }

Yes, I'll send a separate diff for that later.

OK for the new diff?



Index: hello.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/hello.c,v
retrieving revision 1.24
diff -u -p -r1.24 hello.c
--- hello.c     12 Aug 2019 20:21:58 -0000      1.24
+++ hello.c     16 Nov 2019 14:52:10 -0000
@@ -191,12 +191,16 @@ recv_hello(struct iface *iface, struct i
                nbr->priority = hello.rtr_priority;
                /* XXX neighbor address shouldn't be stored on virtual links */
                nbr->addr.s_addr = src.s_addr;
+               ospfe_imsg_compose_rde(IMSG_NEIGHBOR_ADDR, nbr->peerid, 0,
+                   &src, sizeof(src));
        }
 
        if (nbr->addr.s_addr != src.s_addr) {
                log_warnx("%s: neighbor ID %s changed its IP address",
                    __func__, inet_ntoa(nbr->id));
                nbr->addr.s_addr = src.s_addr;
+               ospfe_imsg_compose_rde(IMSG_NEIGHBOR_ADDR, nbr->peerid, 0,
+                   &src, sizeof(src));
        }
 
        nbr->options = hello.opts;
Index: lsupdate.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/lsupdate.c,v
retrieving revision 1.46
diff -u -p -r1.46 lsupdate.c
--- lsupdate.c  15 Jul 2019 18:26:39 -0000      1.46
+++ lsupdate.c  15 Aug 2019 21:10:13 -0000
@@ -470,7 +470,7 @@ ls_retrans_timer(int fd, short event, vo
                        /* ls_retrans_list_free retriggers the timer */
                        return;
                } else if (nbr->iface->type == IF_TYPE_POINTOPOINT)
-                       memcpy(&addr, &nbr->iface->dst, sizeof(addr));
+                       memcpy(&addr, &nbr->addr, sizeof(addr));
                else
                        inet_aton(AllDRouters, &addr);
        } else
Index: neighbor.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/neighbor.c,v
retrieving revision 1.48
diff -u -p -r1.48 neighbor.c
--- neighbor.c  9 Feb 2018 02:14:03 -0000       1.48
+++ neighbor.c  16 Nov 2019 14:53:52 -0000
@@ -312,6 +312,7 @@ nbr_new(u_int32_t nbr_id, struct iface *
        bzero(&rn, sizeof(rn));
        rn.id.s_addr = nbr->id.s_addr;
        rn.area_id.s_addr = nbr->iface->area->id.s_addr;
+       rn.addr.s_addr = nbr->addr.s_addr;
        rn.ifindex = nbr->iface->ifindex;
        rn.state = nbr->state;
        rn.self = self;
Index: ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
retrieving revision 1.108
diff -u -p -r1.108 ospfd.c
--- ospfd.c     16 May 2019 05:49:22 -0000      1.108
+++ ospfd.c     16 Nov 2019 21:36:45 -0000
@@ -911,6 +911,15 @@ merge_interfaces(struct area *a, struct 
                                if_fsm(i, IF_EVT_UP);
                }
 
+               if (i->p2p != xi->p2p) {
+                       /* restart interface to enable or disable DR election */
+                       if (ospfd_process == PROC_OSPF_ENGINE)
+                               if_fsm(i, IF_EVT_DOWN);
+                       i->p2p = xi->p2p;
+                       if (ospfd_process == PROC_OSPF_ENGINE)
+                               if_fsm(i, IF_EVT_UP);
+               }
+
                strlcpy(i->dependon, xi->dependon,
                        sizeof(i->dependon));
                i->depend_ok = xi->depend_ok;
Index: ospfd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.conf.5,v
retrieving revision 1.57
diff -u -p -r1.57 ospfd.conf.5
--- ospfd.conf.5        10 Jun 2019 06:07:15 -0000      1.57
+++ ospfd.conf.5        23 Jun 2019 22:10:32 -0000
@@ -419,6 +419,9 @@ Router.
 .It Ic transmit-delay Ar seconds
 Set the transmit delay.
 The default value is 1; valid range is 1\-3600 seconds.
+.It Ic type p2p
+Set the interface type to point to point.
+This disables the election of a DR and BDR for the given interface.
 .El
 .Sh FILES
 .Bl -tag -width "/etc/ospfd.conf" -compact
Index: ospfd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v
retrieving revision 1.104
diff -u -p -r1.104 ospfd.h
--- ospfd.h     16 May 2019 05:49:22 -0000      1.104
+++ ospfd.h     21 Sep 2019 10:25:32 -0000
@@ -107,6 +107,7 @@ enum imsg_type {
        IMSG_IFINFO,
        IMSG_NEIGHBOR_UP,
        IMSG_NEIGHBOR_DOWN,
+       IMSG_NEIGHBOR_ADDR,
        IMSG_NEIGHBOR_CHANGE,
        IMSG_NEIGHBOR_CAPA,
        IMSG_NETWORK_ADD,
@@ -363,6 +364,7 @@ struct iface {
        u_int8_t                 linkstate;
        u_int8_t                 priority;
        u_int8_t                 passive;
+       u_int8_t                 p2p;
 };
 
 struct ifaddrchange {
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/parse.y,v
retrieving revision 1.98
diff -u -p -r1.98 parse.y
--- parse.y     7 Jun 2019 04:57:45 -0000       1.98
+++ parse.y     24 Oct 2019 20:09:11 -0000
@@ -129,7 +129,7 @@ typedef struct {
 %token AREA INTERFACE ROUTERID FIBPRIORITY FIBUPDATE REDISTRIBUTE RTLABEL
 %token RDOMAIN RFC1583COMPAT STUB ROUTER SPFDELAY SPFHOLDTIME EXTTAG
 %token AUTHKEY AUTHTYPE AUTHMD AUTHMDKEYID
-%token METRIC PASSIVE
+%token METRIC P2P PASSIVE
 %token HELLOINTERVAL FASTHELLOINTERVAL TRANSMITDELAY
 %token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY
 %token SET TYPE
@@ -743,6 +743,10 @@ interfaceopts_l    : interfaceopts_l interf
                ;
 
 interfaceoptsl : PASSIVE               { iface->passive = 1; }
+               | TYPE P2P              {
+                       iface->p2p = 1;
+                       iface->type = IF_TYPE_POINTOPOINT;
+               }
                | DEMOTE STRING         {
                        if (strlcpy(iface->demote_group, $2,
                            sizeof(iface->demote_group)) >=
@@ -833,6 +837,7 @@ lookup(char *s)
                {"msec",                MSEC},
                {"no",                  NO},
                {"on",                  ON},
+               {"p2p",                 P2P},
                {"passive",             PASSIVE},
                {"rdomain",             RDOMAIN},
                {"redistribute",        REDISTRIBUTE},
Index: printconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/printconf.c,v
retrieving revision 1.20
diff -u -p -r1.20 printconf.c
--- printconf.c 28 Dec 2018 19:25:10 -0000      1.20
+++ printconf.c 23 Jun 2019 22:05:55 -0000
@@ -149,6 +149,9 @@ print_iface(struct iface *iface)
                printf("\t\trouter-priority %d\n", iface->priority);
                printf("\t\ttransmit-delay %d\n", iface->transmit_delay);
 
+               if (iface->p2p)
+                       printf("\t\ttype p2p\n");
+
                printf("\t\tauth-type %s\n", if_auth_name(iface->auth_type));
                switch (iface->auth_type) {
                case AUTH_TYPE_NONE:
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.c,v
retrieving revision 1.109
diff -u -p -r1.109 rde.c
--- rde.c       5 Feb 2018 12:11:28 -0000       1.109
+++ rde.c       21 Sep 2019 12:17:09 -0000
@@ -257,6 +257,7 @@ rde_dispatch_imsg(int fd, short event, v
        struct timespec          tp;
        struct lsa              *lsa;
        struct area             *area;
+       struct in_addr           addr;
        struct vertex           *v;
        char                    *buf;
        ssize_t                  n;
@@ -300,6 +301,17 @@ rde_dispatch_imsg(int fd, short event, v
                        break;
                case IMSG_NEIGHBOR_DOWN:
                        rde_nbr_del(rde_nbr_find(imsg.hdr.peerid));
+                       break;
+               case IMSG_NEIGHBOR_ADDR:
+                       if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr))
+                               fatalx("invalid size of OE request");
+                       memcpy(&addr, imsg.data, sizeof(addr));
+
+                       nbr = rde_nbr_find(imsg.hdr.peerid);
+                       if (nbr == NULL)
+                               break;
+
+                       nbr->addr.s_addr = addr.s_addr;
                        break;
                case IMSG_NEIGHBOR_CHANGE:
                        if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(state))
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.h,v
retrieving revision 1.39
diff -u -p -r1.39 rde.h
--- rde.h       14 Mar 2015 02:22:09 -0000      1.39
+++ rde.h       19 Sep 2019 13:46:43 -0000
@@ -66,6 +66,7 @@ struct rde_nbr {
        LIST_ENTRY(rde_nbr)              entry, hash;
        struct in_addr                   id;
        struct in_addr                   area_id;
+       struct in_addr                   addr;
        TAILQ_HEAD(, rde_req_entry)      req_list;
        struct area                     *area;
        struct iface                    *iface;
Index: rde_spf.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde_spf.c,v
retrieving revision 1.77
diff -u -p -r1.77 rde_spf.c
--- rde_spf.c   4 Apr 2019 19:57:08 -0000       1.77
+++ rde_spf.c   29 Sep 2019 21:08:49 -0000
@@ -373,6 +373,7 @@ calc_nexthop(struct vertex *dst, struct 
 {
        struct v_nexthop        *vn;
        struct iface            *iface;
+       struct rde_nbr          *nbr;
        int                      i;
 
        /* case 1 */
@@ -382,10 +383,14 @@ calc_nexthop(struct vertex *dst, struct 
                        if (rtr_link->type != LINK_TYPE_POINTTOPOINT)
                                fatalx("inconsistent SPF tree");
                        LIST_FOREACH(iface, &area->iface_list, entry) {
-                               if (rtr_link->data == iface->addr.s_addr) {
-                                       vertex_nexthop_add(dst, parent,
-                                           iface->dst.s_addr);
-                                       return;
+                               if (rtr_link->data != iface->addr.s_addr)
+                                       continue;
+                               LIST_FOREACH(nbr, &area->nbr_list, entry) {
+                                       if (nbr->ifindex == iface->ifindex) {
+                                               vertex_nexthop_add(dst, parent,
+                                                   nbr->addr.s_addr);
+                                               return;
+                                       }
                                }
                        }
                        fatalx("no interface found for interface");

Reply via email to