summaryrefslogtreecommitdiffstats
path: root/zebra/kernel_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/kernel_socket.c')
-rw-r--r--zebra/kernel_socket.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 8beac71d..aa962a35 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -173,7 +173,9 @@ static const struct message rtm_flag_str[] =
#ifdef RTF_MASK
{RTF_MASK, "MASK"},
#endif /* RTF_MASK */
+#ifdef RTF_CLONING
{RTF_CLONING, "CLONING"},
+#endif /* RTF_CLONING */
{RTF_XRESOLVE, "XRESOLVE"},
{RTF_LLINFO, "LLINFO"},
{RTF_STATIC, "STATIC"},
@@ -236,7 +238,7 @@ af_check (int family)
static void
rtm_flag_dump (int flag)
{
- struct message *mes;
+ const struct message *mes;
static char buf[BUFSIZ];
buf[0] = '\0';
@@ -251,6 +253,25 @@ rtm_flag_dump (int flag)
zlog_debug ("Kernel: %s", buf);
}
+/* NetBSD IPSRCSEL preference readback */
+static int
+if_get_addrpref (const char *ifname, struct sockaddr_in *addr)
+{
+#ifdef SIOCSIFADDRPREF
+ int ret;
+ struct if_addrprefreq ifapr;
+
+ memset (&ifapr, 0, sizeof ifapr);
+ strncpy ((char *)&ifapr.ifap_name, ifname, sizeof ifapr.ifap_name);
+ memcpy (&ifapr.ifap_addr, addr, sizeof (struct sockaddr_in));
+
+ ret = if_ioctl (SIOCGIFADDRPREF, (caddr_t) &ifapr);
+ if (ret == 0)
+ return ifapr.ifap_preference;
+#endif
+ return 0;
+}
+
#ifdef RTM_IFANNOUNCE
/* Interface adding function */
static int
@@ -617,6 +638,7 @@ ifam_read (struct ifa_msghdr *ifam)
short ifnlen = 0;
char isalias = 0;
int flags = 0;
+ int preference = 0;
ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0';
@@ -647,6 +669,9 @@ ifam_read (struct ifa_msghdr *ifam)
*/
ifp->metric = ifam->ifam_metric;
#endif
+ if (sockunion_family (&addr) == AF_INET
+ && ifam->ifam_type == RTM_NEWADDR)
+ preference = if_get_addrpref (ifp->name, &addr.sin);
/* Add connected address. */
switch (sockunion_family (&addr))
@@ -656,7 +681,7 @@ ifam_read (struct ifa_msghdr *ifam)
connected_add_ipv4 (ifp, flags, &addr.sin.sin_addr,
ip_masklen (mask.sin.sin_addr),
&brd.sin.sin_addr,
- (isalias ? ifname : NULL));
+ (isalias ? ifname : NULL), 0, preference);
else
connected_delete_ipv4 (ifp, flags, &addr.sin.sin_addr,
ip_masklen (mask.sin.sin_addr),
@@ -673,7 +698,7 @@ ifam_read (struct ifa_msghdr *ifam)
connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr,
ip6_masklen (mask.sin6.sin6_addr),
&brd.sin6.sin6_addr,
- (isalias ? ifname : NULL));
+ (isalias ? ifname : NULL), 0);
else
connected_delete_ipv6 (ifp,
&addr.sin6.sin6_addr,
@@ -999,9 +1024,14 @@ rtm_write (int message,
if (gate && message == RTM_ADD)
msg.rtm.rtm_flags |= RTF_GATEWAY;
+ /* When RTF_CLONING is unavailable on BSD, should we set some
+ * other flag instead?
+ */
+#ifdef RTF_CLONING
if (! gate && message == RTM_ADD && ifp &&
(ifp->flags & IFF_POINTOPOINT) == 0)
msg.rtm.rtm_flags |= RTF_CLONING;
+#endif /* RTF_CLONING */
/* If no protocol specific gateway is specified, use link
address for gateway. */