summaryrefslogtreecommitdiff
path: root/zebra/kernel_socket.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2020-09-20 20:21:41 -0400
committerDonald Sharp <sharpd@nvidia.com>2020-09-20 20:53:27 -0400
commit8c36640b7cd2b880201ee8510155719d3145d457 (patch)
tree06ef187496d42173eb7865aa1f2ad223477947b6 /zebra/kernel_socket.c
parent1f79037b72f0ec93153f9505a11bce9812429993 (diff)
zebra: Allow FreeBSD to set and delete addresses from an interface
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>
Diffstat (limited to 'zebra/kernel_socket.c')
-rw-r--r--zebra/kernel_socket.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 02963651a0..2b6caace8e 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -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