On Mon, Jul 04, 2011 at 06:13:29AM +0200, Claudio Jeker wrote:
> On Tue, Jun 28, 2011 at 04:42:09PM +1000, David Gwynne wrote:
> > this works great for me. i'll pressure claudio@ to have a look at it over 
> > the
> > next week or two.
> > 
> 
> I just commited this (a modified version of the diff by Patrick Coleman)
> and will now look at the interface add problem (and Martin Pelikan's
> diff which needs some changes as well).
> 

I refactored the code a bit since I don't like that ospfe is forwarding
link state changes to the rde. The rde should get the change directly from
the parent and the ospfe only needs to send the state changes of the FSM
to the RDE. IMO this is more clear. Maybe I should create a new IMSG type
for the state change but that is just the icing on the cake.

please test
-- 
:wq Claudio

? obj
Index: interface.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v
retrieving revision 1.18
diff -u -p -r1.18 interface.c
--- interface.c 4 Jul 2011 04:34:14 -0000       1.18
+++ interface.c 7 Jul 2011 05:05:01 -0000
@@ -145,12 +145,12 @@ if_fsm(struct iface *iface, enum iface_e
        if (iface->state != old_state) {
                orig_rtr_lsa(iface);
                orig_link_lsa(iface);
+
+               /* state change inform RDE */
+               ospfe_imsg_compose_rde(IMSG_IFINFO, iface->self->peerid, 0,
+                   &iface->state, sizeof(iface->state));
        }
        
-       /* Inform RDE in any case since the link state may have changed */
-       ospfe_imsg_compose_rde(IMSG_IFINFO,
-           iface->self->peerid, 0, iface, sizeof(struct iface));
-
        if (old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT) &&
            (iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0)
                ospfe_demote_iface(iface, 0);
Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.33
diff -u -p -r1.33 kroute.c
--- kroute.c    7 Jul 2011 03:56:59 -0000       1.33
+++ kroute.c    7 Jul 2011 05:05:01 -0000
@@ -812,10 +812,13 @@ if_change(u_short ifindex, int flags, st
        if (wasvalid == isvalid)
                return;         /* nothing changed wrt validity */
 
-       /* notify ospfe about interface link state */
-       if (iface->cflags & F_IFACE_CONFIGURED)
+       /* inform engine and rde about state change if interface is used */
+       if (iface->cflags & F_IFACE_CONFIGURED) {
                main_imsg_compose_ospfe(IMSG_IFINFO, 0, iface,
                    sizeof(struct iface));
+               main_imsg_compose_rde(IMSG_IFINFO, 0, iface,
+                   sizeof(struct iface));
+       }
 
        /* update redistribute list */
        RB_FOREACH(kr, kroute_tree, &krt) {
Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v
retrieving revision 1.36
diff -u -p -r1.36 ospfe.c
--- ospfe.c     7 Jul 2011 04:13:23 -0000       1.36
+++ ospfe.c     7 Jul 2011 05:05:01 -0000
@@ -286,9 +286,10 @@ ospfe_dispatch_main(int fd, short event,
                        iface = if_find(ifp->ifindex);
                        if (iface == NULL)
                                fatalx("interface lost in ospfe");
-                       iface->flags = ifp->flags;
-                       iface->linkstate = ifp->linkstate;
 
+                       if_update(iface, ifp->mtu, ifp->flags, ifp->media_type,
+                           ifp->linkstate, ifp->baudrate);
+                           
                        if ((iface->flags & IFF_UP) &&
                            LINK_STATE_IS_UP(iface->linkstate)) {
                                if_fsm(iface, IF_EVT_UP);
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.57
diff -u -p -r1.57 rde.c
--- rde.c       7 Jul 2011 04:37:56 -0000       1.57
+++ rde.c       7 Jul 2011 05:05:01 -0000
@@ -252,7 +252,6 @@ rde_dispatch_imsg(int fd, short event, v
        struct lsa              *lsa;
        struct area             *area;
        struct vertex           *v;
-       struct iface            *iface, *ifp;
        char                    *buf;
        ssize_t                  n;
        time_t                   now;
@@ -578,32 +577,16 @@ rde_dispatch_imsg(int fd, short event, v
                        break;
                case IMSG_IFINFO:
                        if (imsg.hdr.len != IMSG_HEADER_SIZE +
-                           sizeof(struct iface))
+                           sizeof(int))
                                fatalx("IFINFO imsg with wrong len");
 
-                       ifp = imsg.data;
-
-                       iface = if_find(ifp->ifindex);
-                       if (iface == NULL)
-                               fatalx("interface lost in rde");
-
-                       /* 
-                        * Resend LSAs if interface flags change -
-                        * carp/passive interfaces can come up and down
-                        * without changing OSPF state.
-                        */
-                       if ((iface->state != ifp->state) || 
-                           (iface->linkstate != ifp->linkstate) || 
-                           (iface->flags != ifp->flags)) {
-                               iface->state = ifp->state;
-                               iface->flags = ifp->flags;
-                               iface->linkstate = ifp->linkstate;
+                       nbr = rde_nbr_find(imsg.hdr.peerid);
+                       if (nbr == NULL)
+                               fatalx("IFINFO imsg with bad peerid");
+                       memcpy(&nbr->iface->state, imsg.data, sizeof(int));
 
-                               area = area_find(rdeconf, iface->area_id);
-                               if (!area)
-                                       fatalx("interface lost area");
-                               orig_intra_area_prefix_lsas(area);
-                       }
+                       /* Resend LSAs if interface state changes. */
+                       orig_intra_area_prefix_lsas(nbr->area);
                        break;
                case IMSG_CTL_LOG_VERBOSE:
                        /* already checked by ospfe */
@@ -632,7 +615,7 @@ rde_dispatch_parent(int fd, short event,
 {
        static struct area      *narea;
        struct area             *area;
-       struct iface            *iface;
+       struct iface            *iface, *ifp;
        struct ifaddrchange     *ifc;
        struct iface_addr       *ia, *nia;
        struct imsg              imsg;
@@ -644,7 +627,7 @@ rde_dispatch_parent(int fd, short event,
        struct vertex           *v;
        struct rt_node          *rn;
        ssize_t                  n;
-       int                      shut = 0;
+       int                      shut = 0, wasvalid;
        unsigned int             ifindex;
 
        if (event & EV_READ) {
@@ -715,8 +698,33 @@ rde_dispatch_parent(int fd, short event,
                                rde_send_change_kroute(rn);
                        else
                                /* should not happen */
-                               imsg_compose_event(iev_main, 
IMSG_KROUTE_DELETE, 0,
-                                   0, -1, &kr, sizeof(kr));
+                               imsg_compose_event(iev_main, IMSG_KROUTE_DELETE,
+                                   0, 0, -1, &kr, sizeof(kr));
+                       break;
+               case IMSG_IFINFO:
+                       if (imsg.hdr.len != IMSG_HEADER_SIZE +
+                           sizeof(struct iface))
+                               fatalx("IFINFO imsg with wrong len");
+
+                       ifp = imsg.data;
+                       iface = if_find(ifp->ifindex);
+                       if (iface == NULL)
+                               fatalx("interface lost in rde");
+
+                       wasvalid = (iface->flags & IFF_UP) &&
+                           LINK_STATE_IS_UP(iface->linkstate);
+
+                       if_update(iface, ifp->mtu, ifp->flags, ifp->media_type,
+                           ifp->linkstate, ifp->baudrate);
+
+                       /* Resend LSAs if interface state changes. */
+                       if (wasvalid != (iface->flags & IFF_UP) &&
+                           LINK_STATE_IS_UP(iface->linkstate)) {
+                               area = area_find(rdeconf, iface->area_id);
+                               if (!area)
+                                       fatalx("interface lost area");
+                               orig_intra_area_prefix_lsas(area);
+                       }
                        break;
                case IMSG_IFADD:
                        if ((iface = malloc(sizeof(struct iface))) == NULL)

Reply via email to