diff options
author | David Lamparter <equinox@diac24.net> | 2010-02-03 20:05:09 +0100 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2010-02-04 02:52:32 +0100 |
commit | 85e53d51f723112b44075c658431d9700facd4c0 (patch) | |
tree | 9caa82e27309a1690d8c55e3bf740fac92ecd8f9 /zebra | |
parent | 316ef35ac30edcd56be22a551897f47ebeb91b29 (diff) | |
download | quagga-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.c | 3 | ||||
-rw-r--r-- | zebra/connected.h | 2 | ||||
-rw-r--r-- | zebra/if_ioctl.c | 4 | ||||
-rw-r--r-- | zebra/if_ioctl_solaris.c | 2 | ||||
-rw-r--r-- | zebra/interface.c | 4 | ||||
-rw-r--r-- | zebra/kernel_null.c | 2 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 25 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 2 |
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, |