summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2010-02-03 20:05:09 +0100
committerDavid Lamparter <equinox@diac24.net>2010-02-04 02:52:32 +0100
commit85e53d51f723112b44075c658431d9700facd4c0 (patch)
tree9caa82e27309a1690d8c55e3bf740fac92ecd8f9 /zebra
parent316ef35ac30edcd56be22a551897f47ebeb91b29 (diff)
downloadquagga-85e53d51f723112b44075c658431d9700facd4c0.tar.bz2
quagga-85e53d51f723112b44075c658431d9700facd4c0.tar.xz
zebra: NetBSD: get IPSRCSEL preference value from kernel
fetch the address preference value from the kernel through SIOCGIFADDRPREF and pass it to quagga through connected_add_ipv4, which stores it in struct connected->preference. IPSRCSEL is a NetBSD kernel option(4), documented in in_getifa(9) and is available since NetBSD 4.0 but not enabled in default GENERIC.
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c3
-rw-r--r--zebra/connected.h2
-rw-r--r--zebra/if_ioctl.c4
-rw-r--r--zebra/if_ioctl_solaris.c2
-rw-r--r--zebra/interface.c4
-rw-r--r--zebra/kernel_null.c2
-rw-r--r--zebra/kernel_socket.c25
-rw-r--r--zebra/rt_netlink.c2
8 files changed, 36 insertions, 8 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 82c531e4..0c22582d 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -269,7 +269,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
void
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
u_char prefixlen, struct in_addr *broad,
- const char *label, unsigned scope)
+ const char *label, unsigned scope, int preference)
{
struct prefix_ipv4 *p;
struct connected *ifc;
@@ -342,6 +342,7 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
ifc->scope = scope;
+ ifc->preference = preference;
/* nothing to do? */
if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
diff --git a/zebra/connected.h b/zebra/connected.h
index 5ea6d54d..ede75120 100644
--- a/zebra/connected.h
+++ b/zebra/connected.h
@@ -31,7 +31,7 @@ connected_check_ptp (struct interface *ifp, struct prefix *p, struct prefix *d);
extern void
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
u_char prefixlen, struct in_addr *broad,
- const char *label, unsigned scope);
+ const char *label, unsigned scope, int preference);
extern void
connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c
index e85c744c..36732704 100644
--- a/zebra/if_ioctl.c
+++ b/zebra/if_ioctl.c
@@ -276,7 +276,7 @@ if_getaddrs (void)
}
connected_add_ipv4 (ifp, flags, &addr->sin_addr,
- prefixlen, dest_pnt, NULL, 0);
+ prefixlen, dest_pnt, NULL, 0, 0);
}
#ifdef HAVE_IPV6
if (ifap->ifa_addr->sa_family == AF_INET6)
@@ -412,7 +412,7 @@ if_get_addr (struct interface *ifp)
/* Set address to the interface. */
- connected_add_ipv4 (ifp, flags, &addr.sin_addr, prefixlen, dest_pnt, NULL, 0);
+ connected_add_ipv4 (ifp, flags, &addr.sin_addr, prefixlen, dest_pnt, NULL, 0, 0);
return 0;
}
diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c
index 86fcc484..736232e8 100644
--- a/zebra/if_ioctl_solaris.c
+++ b/zebra/if_ioctl_solaris.c
@@ -327,7 +327,7 @@ if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label)
/* Set address to the interface. */
if (af == AF_INET)
connected_add_ipv4 (ifp, flags, &SIN (addr)->sin_addr, prefixlen,
- (struct in_addr *) dest_pnt, label, 0);
+ (struct in_addr *) dest_pnt, label, 0, 0);
#ifdef HAVE_IPV6
else if (af == AF_INET6)
connected_add_ipv6 (ifp, flags, &SIN6 (addr)->sin6_addr, prefixlen,
diff --git a/zebra/interface.c b/zebra/interface.c
index 11c99f73..590a177d 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -599,6 +599,10 @@ connected_dump_vty (struct vty *vty, struct connected *connected)
if (connected->scope != 0)
vty_out (vty, " scope %s", connected_scope_name (connected->scope));
#endif
+#ifdef SIOCSIFADDRPREF
+ if (connected->preference != 0)
+ vty_out (vty, " preference %d", connected->preference);
+#endif
if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
vty_out (vty, " secondary");
diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c
index fa90b99b..f83c2345 100644
--- a/zebra/kernel_null.c
+++ b/zebra/kernel_null.c
@@ -25,7 +25,7 @@ int kernel_address_add_ipv4 (struct interface *a, struct connected *b)
SET_FLAG (b->conf, ZEBRA_IFC_REAL);
connected_add_ipv4 (a, 0, &b->address->u.prefix4, b->address->prefixlen,
(b->destination ? &b->destination->u.prefix4 : NULL),
- NULL, 0);
+ NULL, 0, 0);
return 0;
}
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 5a0359ea..aa962a35 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -253,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
@@ -619,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';
@@ -649,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))
@@ -658,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), 0);
+ (isalias ? ifname : NULL), 0, preference);
else
connected_delete_ipv4 (ifp, flags, &addr.sin.sin_addr,
ip_masklen (mask.sin.sin_addr),
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 92ce8d69..d25543ff 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -617,7 +617,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
if (h->nlmsg_type == RTM_NEWADDR)
connected_add_ipv4 (ifp, flags,
(struct in_addr *) addr, ifa->ifa_prefixlen,
- (struct in_addr *) broad, label, ifa->ifa_scope);
+ (struct in_addr *) broad, label, ifa->ifa_scope, 0);
else
connected_delete_ipv4 (ifp, flags,
(struct in_addr *) addr, ifa->ifa_prefixlen,