Handle the case of an autoconf interface changing its rdomain.

To avoide code duplication have get_icmp6ev_by_rdomain() either return
an existing icmp6ev in the correct rdomain or allocate one.

OK?

diff --git frontend.c frontend.c
index 3bf418ba31e..624ff5562f3 100644
--- frontend.c
+++ frontend.c
@@ -502,7 +502,6 @@ void
 update_iface(uint32_t if_index, char* if_name)
 {
        struct iface            *iface;
-       struct icmp6_ev         *icmp6ev;
        struct imsg_ifinfo       imsg_ifinfo;
        int                      flags, xflags, ifrdomain;
 
@@ -516,32 +515,29 @@ update_iface(uint32_t if_index, char* if_name)
        if((ifrdomain = get_ifrdomain(if_name)) == -1)
                return;
 
-       if ((iface = get_iface_by_id(if_index)) == NULL) {
+       iface = get_iface_by_id(if_index);
+
+       if (iface != NULL) {
+               if (iface->rdomain != ifrdomain) {
+                       if (iface->icmp6ev != NULL) {
+                               iface->icmp6ev->refcnt--;
+                               if (iface->icmp6ev->refcnt == 0) {
+                                       event_del(&iface->icmp6ev->ev);
+                                       close(EVENT_FD(&iface->icmp6ev->ev));
+                                       free(iface->icmp6ev);
+                               }
+                               iface->icmp6ev = NULL;
+                       }
+                       iface->rdomain = ifrdomain;
+                       iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain);
+               }
+       } else {
                if ((iface = calloc(1, sizeof(*iface))) == NULL)
                        fatal("calloc");
                iface->if_index = if_index;
                iface->rdomain = ifrdomain;
+               iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain);
 
-               if ((icmp6ev = get_icmp6ev_by_rdomain(ifrdomain)) == NULL) {
-                       if ((icmp6ev = calloc(1, sizeof(*icmp6ev))) == NULL)
-                               fatal("calloc");
-                       icmp6ev->rcviov[0].iov_base = (caddr_t)icmp6ev->answer;
-                       icmp6ev->rcviov[0].iov_len = sizeof(icmp6ev->answer);
-                       icmp6ev->rcvmhdr.msg_name = (caddr_t)&icmp6ev->from;
-                       icmp6ev->rcvmhdr.msg_namelen = sizeof(icmp6ev->from);
-                       icmp6ev->rcvmhdr.msg_iov = icmp6ev->rcviov;
-                       icmp6ev->rcvmhdr.msg_iovlen = 1;
-                       icmp6ev->rcvmhdr.msg_controllen =
-                           CMSG_SPACE(sizeof(struct in6_pktinfo)) +
-                           CMSG_SPACE(sizeof(int));
-                       if ((icmp6ev->rcvmhdr.msg_control = malloc(icmp6ev->
-                           rcvmhdr.msg_controllen)) == NULL)
-                               fatal("malloc");
-                       frontend_imsg_compose_main(IMSG_OPEN_ICMP6SOCK, 0,
-                           &ifrdomain, sizeof(ifrdomain));
-               }
-               iface->icmp6ev = icmp6ev;
-               iface->icmp6ev->refcnt++;
                LIST_INSERT_HEAD(&interfaces, iface, entries);
        }
 
@@ -1121,13 +1117,35 @@ struct icmp6_ev*
 get_icmp6ev_by_rdomain(int rdomain)
 {
        struct iface    *iface;
+       struct icmp6_ev *icmp6ev = NULL;
 
        LIST_FOREACH (iface, &interfaces, entries) {
-               if (iface->rdomain == rdomain)
-                       return (iface->icmp6ev);
+               if (iface->rdomain == rdomain) {
+                       icmp6ev = iface->icmp6ev;
+                       break;
+               }
        }
 
-       return (NULL);
+       if (icmp6ev == NULL) {
+               if ((icmp6ev = calloc(1, sizeof(*icmp6ev))) == NULL)
+                       fatal("calloc");
+               icmp6ev->rcviov[0].iov_base = (caddr_t)icmp6ev->answer;
+               icmp6ev->rcviov[0].iov_len = sizeof(icmp6ev->answer);
+               icmp6ev->rcvmhdr.msg_name = (caddr_t)&icmp6ev->from;
+               icmp6ev->rcvmhdr.msg_namelen = sizeof(icmp6ev->from);
+               icmp6ev->rcvmhdr.msg_iov = icmp6ev->rcviov;
+               icmp6ev->rcvmhdr.msg_iovlen = 1;
+               icmp6ev->rcvmhdr.msg_controllen =
+                   CMSG_SPACE(sizeof(struct in6_pktinfo)) +
+                   CMSG_SPACE(sizeof(int));
+               if ((icmp6ev->rcvmhdr.msg_control = malloc(icmp6ev->
+                   rcvmhdr.msg_controllen)) == NULL)
+                       fatal("malloc");
+               frontend_imsg_compose_main(IMSG_OPEN_ICMP6SOCK, 0,
+                   &rdomain, sizeof(rdomain));
+       }
+       icmp6ev->refcnt++;
+       return (icmp6ev);
 }
 
 void
-- 
2.29.2



-- 
I'm not entirely sure you are real.

Reply via email to