]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: Allow FreeBSD to set and delete addresses from an interface
authorDonald Sharp <sharpd@nvidia.com>
Mon, 21 Sep 2020 00:21:41 +0000 (20:21 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 21 Sep 2020 00:53:27 +0000 (20:53 -0400)
This series of events:

$ sudo ifconfig lo0 add 4.4.4.4/32
$ sudo ifconfig lo0 inet 4.4.4.4/32 delete

would end up leaving the 4.4.4.4/32 address on the interface under
freebsd.

This all boils down to the fact that the interface is not
considered connected yet we have a destination.  If the
destination is the same and we are not connected ignore
it on freebsd.

I am sure there are other fun scenarios that someone
will have to squirrel out.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
zebra/kernel_socket.c

index 02963651a0a57d6370c523b37726371ebb7df8a1..2b6caace8ec09e5d44970ddba673a044cdd5b7dd 100644 (file)
@@ -865,6 +865,7 @@ int ifam_read(struct ifa_msghdr *ifam)
 {
        struct interface *ifp = NULL;
        union sockunion addr, mask, brd;
+       bool dest_same = false;
        char ifname[INTERFACE_NAMSIZ];
        short ifnlen = 0;
        char isalias = 0;
@@ -891,6 +892,10 @@ int ifam_read(struct ifa_msghdr *ifam)
           rely upon the interface type. */
        if (if_is_pointopoint(ifp))
                SET_FLAG(flags, ZEBRA_IFA_PEER);
+       else {
+               if (memcmp(&addr, &brd, sizeof(addr)) == 0)
+                       dest_same = true;
+       }
 
 #if 0
   /* it might seem cute to grab the interface metric here, however
@@ -907,13 +912,14 @@ int ifam_read(struct ifa_msghdr *ifam)
                if (ifam->ifam_type == RTM_NEWADDR)
                        connected_add_ipv4(ifp, flags, &addr.sin.sin_addr,
                                           ip_masklen(mask.sin.sin_addr),
-                                          &brd.sin.sin_addr,
+                                          dest_same ? NULL : &brd.sin.sin_addr,
                                           (isalias ? ifname : NULL),
                                           METRIC_MAX);
                else
                        connected_delete_ipv4(ifp, flags, &addr.sin.sin_addr,
                                              ip_masklen(mask.sin.sin_addr),
-                                             &brd.sin.sin_addr);
+                                             dest_same ? NULL
+                                                       : &brd.sin.sin_addr);
                break;
        case AF_INET6:
                /* Unset interface index from link-local address when IPv6 stack