summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysdep/bsd-netlink/Makefile6
-rw-r--r--sysdep/bsd-netlink/netlink-sys.h29
l---------sysdep/bsd-netlink/netlink.Y1
l---------sysdep/bsd-netlink/netlink.c1
-rw-r--r--sysdep/bsd/sysio.h34
-rw-r--r--sysdep/cf/bsd-netlink.h11
-rw-r--r--sysdep/cf/linux.h1
-rw-r--r--sysdep/linux/netlink-sys.h63
-rw-r--r--sysdep/linux/netlink.c53
9 files changed, 137 insertions, 62 deletions
diff --git a/sysdep/bsd-netlink/Makefile b/sysdep/bsd-netlink/Makefile
new file mode 100644
index 00000000..188ac8de
--- /dev/null
+++ b/sysdep/bsd-netlink/Makefile
@@ -0,0 +1,6 @@
+src := netlink.c
+obj := $(src-o-files)
+$(all-daemon)
+$(conf-y-targets): $(s)netlink.Y
+
+tests_objs := $(tests_objs) $(src-o-files)
diff --git a/sysdep/bsd-netlink/netlink-sys.h b/sysdep/bsd-netlink/netlink-sys.h
new file mode 100644
index 00000000..a6e5052b
--- /dev/null
+++ b/sysdep/bsd-netlink/netlink-sys.h
@@ -0,0 +1,29 @@
+/*
+ * Netlink FreeBSD-specific functions
+ *
+ * (c) 2022 Alexander Chernikov <melifaro@FreeBSD.org>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_NETLINK_SYS_H_
+#define _BIRD_NETLINK_SYS_H_
+
+#include <netlink/netlink.h>
+#include <netlink/netlink_route.h>
+
+#ifndef AF_MPLS
+#define AF_MPLS 39
+#endif
+
+#ifndef SO_RCVBUFFORCE
+#define SO_RCVBUFFORCE SO_RCVBUF
+#endif
+
+static inline int
+netlink_error_to_os(int error)
+{
+ return (error);
+}
+
+#endif
diff --git a/sysdep/bsd-netlink/netlink.Y b/sysdep/bsd-netlink/netlink.Y
new file mode 120000
index 00000000..cde7f012
--- /dev/null
+++ b/sysdep/bsd-netlink/netlink.Y
@@ -0,0 +1 @@
+../linux/netlink.Y \ No newline at end of file
diff --git a/sysdep/bsd-netlink/netlink.c b/sysdep/bsd-netlink/netlink.c
new file mode 120000
index 00000000..d9257568
--- /dev/null
+++ b/sysdep/bsd-netlink/netlink.c
@@ -0,0 +1 @@
+../linux/netlink.c \ No newline at end of file
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h
index f1887fb4..b6b42b1e 100644
--- a/sysdep/bsd/sysio.h
+++ b/sysdep/bsd/sysio.h
@@ -15,8 +15,23 @@
#ifdef __FreeBSD__
/* Should be defined in sysdep/cf/bsd.h, but it is flavor-specific */
#define CONFIG_DONTROUTE_UNICAST
+
+#if __FreeBSD_version >= 1201000
+#define CONFIG_USE_IP_MREQN
+#endif
+
#endif
+
+#ifdef __OpenBSD__
+
+#if OpenBSD >= 202105
+#define CONFIG_USE_IP_MREQN
+#endif
+
+#endif
+
+
#ifdef __NetBSD__
#ifndef IP_RECVTTL
@@ -29,6 +44,7 @@
#endif
+
#ifdef __DragonFly__
#define TCP_MD5SIG TCP_SIGNATURE_ENABLE
#endif
@@ -45,13 +61,21 @@
#define INIT_MREQ4(maddr,ifa) \
{ .imr_multiaddr = ipa_to_in4(maddr), .imr_interface = ip4_to_in4(ifa->sysdep) }
+#define INIT_MREQN4(maddr,ifa) \
+ { .imr_multiaddr = ipa_to_in4(maddr), .imr_ifindex = ifa->index }
+
static inline int
sk_setup_multicast4(sock *s)
{
- struct in_addr ifa = ip4_to_in4(s->iface->sysdep);
u8 ttl = s->ttl;
u8 n = 0;
+#ifdef CONFIG_USE_IP_MREQN
+ struct ip_mreqn ifa = { .imr_ifindex = s->iface->index };
+#else
+ struct in_addr ifa = ip4_to_in4(s->iface->sysdep);
+#endif
+
/* This defines where should we send _outgoing_ multicasts */
if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_IF, &ifa, sizeof(ifa)) < 0)
ERR("IP_MULTICAST_IF");
@@ -68,7 +92,11 @@ sk_setup_multicast4(sock *s)
static inline int
sk_join_group4(sock *s, ip_addr maddr)
{
+#ifdef CONFIG_USE_IP_MREQN
+ struct ip_mreqn mr = INIT_MREQN4(maddr, s->iface);
+#else
struct ip_mreq mr = INIT_MREQ4(maddr, s->iface);
+#endif
if (setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
ERR("IP_ADD_MEMBERSHIP");
@@ -79,7 +107,11 @@ sk_join_group4(sock *s, ip_addr maddr)
static inline int
sk_leave_group4(sock *s, ip_addr maddr)
{
+#ifdef CONFIG_USE_IP_MREQN
+ struct ip_mreqn mr = INIT_MREQN4(maddr, s->iface);
+#else
struct ip_mreq mr = INIT_MREQ4(maddr, s->iface);
+#endif
if (setsockopt(s->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mr, sizeof(mr)) < 0)
ERR("IP_ADD_MEMBERSHIP");
diff --git a/sysdep/cf/bsd-netlink.h b/sysdep/cf/bsd-netlink.h
index 09149dc4..69297867 100644
--- a/sysdep/cf/bsd-netlink.h
+++ b/sysdep/cf/bsd-netlink.h
@@ -17,16 +17,7 @@
#define CONFIG_INCLUDE_SYSIO_H "sysdep/bsd/sysio.h"
#define CONFIG_INCLUDE_KRTSYS_H "sysdep/linux/krt-sys.h"
-
-#define CONFIG_FREEBSD_NETLINK
-
-#ifndef AF_MPLS
-#define AF_MPLS 39
-#endif
-
-#ifndef SO_RCVBUFFORCE
-#define SO_RCVBUFFORCE SO_RCVBUF
-#endif
+#define CONFIG_INCLUDE_NLSYS_H "sysdep/bsd-netlink/netlink-sys.h"
/*
Link: sysdep/unix
diff --git a/sysdep/cf/linux.h b/sysdep/cf/linux.h
index 85598c10..9c37dd8a 100644
--- a/sysdep/cf/linux.h
+++ b/sysdep/cf/linux.h
@@ -16,6 +16,7 @@
#define CONFIG_INCLUDE_SYSIO_H "sysdep/linux/sysio.h"
#define CONFIG_INCLUDE_KRTSYS_H "sysdep/linux/krt-sys.h"
+#define CONFIG_INCLUDE_NLSYS_H "sysdep/linux/netlink-sys.h"
#define CONFIG_LINUX_NETLINK
diff --git a/sysdep/linux/netlink-sys.h b/sysdep/linux/netlink-sys.h
new file mode 100644
index 00000000..4c99307b
--- /dev/null
+++ b/sysdep/linux/netlink-sys.h
@@ -0,0 +1,63 @@
+/*
+ * BIRD -- Linux Netlink Interface
+ *
+ * (c) 1999--2000 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_NETLINK_SYS_H_
+#define _BIRD_NETLINK_SYS_H_
+
+#include <asm/types.h>
+#include <linux/if.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#ifdef HAVE_MPLS_KERNEL
+#include <linux/lwtunnel.h>
+#endif
+
+#ifndef MSG_TRUNC /* Hack: Several versions of glibc miss this one :( */
+#define MSG_TRUNC 0x20
+#endif
+
+#ifndef IFA_FLAGS
+#define IFA_FLAGS 8
+#endif
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP 0x10000
+#endif
+
+#ifndef RTA_TABLE
+#define RTA_TABLE 15
+#endif
+
+#ifndef RTA_VIA
+#define RTA_VIA 18
+#endif
+
+#ifndef RTA_NEWDST
+#define RTA_NEWDST 19
+#endif
+
+#ifndef RTA_ENCAP_TYPE
+#define RTA_ENCAP_TYPE 21
+#endif
+
+#ifndef RTA_ENCAP
+#define RTA_ENCAP 22
+#endif
+
+#ifndef NETLINK_GET_STRICT_CHK
+#define NETLINK_GET_STRICT_CHK 12
+#endif
+
+static inline int
+netlink_error_to_os(int error)
+{
+ return -error;
+}
+
+#endif
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 288261f5..0609fde8 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -28,56 +28,7 @@
#include "lib/macro.h"
#include "conf/conf.h"
-#ifdef CONFIG_LINUX_NETLINK
-#include <asm/types.h>
-#include <linux/if.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#endif
-#ifdef CONFIG_FREEBSD_NETLINK
-#include <netlink/netlink.h>
-#include <netlink/netlink_route.h>
-#endif
-
-#ifdef HAVE_MPLS_KERNEL
-#include <linux/lwtunnel.h>
-#endif
-
-#ifndef MSG_TRUNC /* Hack: Several versions of glibc miss this one :( */
-#define MSG_TRUNC 0x20
-#endif
-
-#ifndef IFA_FLAGS
-#define IFA_FLAGS 8
-#endif
-
-#ifndef IFF_LOWER_UP
-#define IFF_LOWER_UP 0x10000
-#endif
-
-#ifndef RTA_TABLE
-#define RTA_TABLE 15
-#endif
-
-#ifndef RTA_VIA
-#define RTA_VIA 18
-#endif
-
-#ifndef RTA_NEWDST
-#define RTA_NEWDST 19
-#endif
-
-#ifndef RTA_ENCAP_TYPE
-#define RTA_ENCAP_TYPE 21
-#endif
-
-#ifndef RTA_ENCAP
-#define RTA_ENCAP 22
-#endif
-
-#ifndef NETLINK_GET_STRICT_CHK
-#define NETLINK_GET_STRICT_CHK 12
-#endif
+#include CONFIG_INCLUDE_NLSYS_H
#define krt_ipv4(p) ((p)->af == AF_INET)
@@ -416,7 +367,7 @@ nl_error(struct nlmsghdr *h, int ignore_esrch)
return ENOBUFS;
}
e = (struct nlmsgerr *) NLMSG_DATA(h);
- ec = -e->error;
+ ec = netlink_error_to_os(e->error);
if (ec && !(ignore_esrch && (ec == ESRCH)))
log_rl(&rl_netlink_err, L_WARN "Netlink: %s", strerror(ec));
return ec;