tables.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley 4.3 BSD
* under license from the Regents of the University of California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Routing Table Management Daemon
*/
#include "defs.h"
/*
* Size of routing socket message used by in.ripngd which includes the header,
* space for the RTA_DST, RTA_GATEWAY and RTA_NETMASK (each a sockaddr_in6)
* plus space for the RTA_IFP (a sockaddr_dl).
*/
#define RIPNG_RTM_MSGLEN sizeof (struct rt_msghdr) + \
sizeof (struct sockaddr_in6) + \
sizeof (struct sockaddr_in6) + \
sizeof (struct sockaddr_in6) + \
sizeof (struct sockaddr_dl)
static int rtmseq; /* rtm_seq sequence number */
static int rtsock; /* Routing socket */
/* simulate vax insque and remque instructions. */
typedef struct vq {
} vq_t;
static void
{
char buf1[INET6_ADDRSTRLEN];
char buf2[INET6_ADDRSTRLEN];
char buf3[INET6_ADDRSTRLEN];
sizeof (buf2));
sizeof (buf3));
buf3,
}
static void
{
char buf1[INET6_ADDRSTRLEN];
char buf2[INET6_ADDRSTRLEN];
}
/*
* Computes a hash by XOR-ing the (up to sixteen) octets that make up an IPv6
* address. This function assumes that that there are no one-bits in the
* address beyond the prefix length.
*/
static uint8_t
{
int i;
return (val);
}
/*
* Given a prefix length, fill in the struct in6_addr representing an IPv6
* netmask.
*/
static void
{
int i;
if (mask != 0)
}
void
{
int j;
if (bits != 0) {
j++;
}
for (; j < 16; j++)
}
/*
* Lookup dst in the tables for an exact match.
*/
struct rt_entry *
{
return (NULL);
continue;
return (rt);
}
return (NULL);
}
/*
* Given an IPv6 prefix (destination and prefix length), a gateway, an
* interface name and route flags, send down the requested command returning
* the return value and errno (in the case of error) from the write() on the
* routing socket.
*/
static int
{
int rlen;
return (-1);
"rtcmd: write to routing socket got only %d for rlen\n",
rlen);
}
return (rlen);
}
void
{
int rlen;
if (metric >= HOPCNT_INFINITY)
return;
return;
}
/*
* In the event of an allocation failure, log the error and
* continue since on the next update another attempt will be
* made.
*/
return;
}
if (prefix_length == IPV6_ABITS)
if (ifroute) {
} else {
}
/*
* If the RTM_ADD fails because the gateway is unreachable
* from this host, discard the entry. This should never
* happen.
*/
if (rlen < 0) {
}
if (errno == ENETUNREACH) {
}
} else if (rlen < RIPNG_RTM_MSGLEN) {
}
}
}
/*
* Handle the case when the metric changes but the gateway is the same (or the
* interface index associated with the gateway changes), or when both gateway
* and metric changes, or when only the gateway changes but the existing route
* is more than one-half of EXPIRE_TIME in age. Note that routes with metric >=
* HOPCNT_INFINITY are not in the kernel.
*/
void
{
int oldmetric;
int rlen;
if (metric >= HOPCNT_INFINITY) {
return;
}
if (oldmetric >= HOPCNT_INFINITY)
else
if (dokern || metricchanged) {
"rtchange: changing route from "
"interface %s (timed out)",
} else {
"rtchange: "
"changing route no interface for route");
}
}
if (dokern) {
}
else
}
if (dokerndelete) {
if (rlen < 0) {
"rtchange: RTM_ADD: %m");
}
} else if (rlen < RIPNG_RTM_MSGLEN) {
}
if (rlen < 0) {
} else if (rlen < RIPNG_RTM_MSGLEN) {
}
} else if (rlen < RIPNG_RTM_MSGLEN) {
}
}
}
}
void
{
int rlen;
if (rlen < 0) {
} else if (rlen < RIPNG_RTM_MSGLEN) {
}
}
}
}
void
{
"rtdelete: "
"deleting route to interface %s (timed out)",
}
}
}
/*
* Mark all the routes heard off a particular interface "down". Unlike the
* routes managed by in.routed, all of these routes have an interface associated
* with them.
*/
void
{
int i;
for (i = IPV6_ABITS; i >= 0; i--) {
if (net_hashes[i] == NULL)
continue;
for (rh = net_hashes[i];
}
}
}
}
}
/*
* Called when the subnetmask has changed on one or more interfaces.
* Re-evaluates all non-interface routes by doing a rtchange so that
* routes that were believed to be host routes before the netmask change
* can be converted to network routes and vice versa.
*/
void
rtchangeall(void)
{
int i;
for (i = IPV6_ABITS; i >= 0; i--) {
if (net_hashes[i] == NULL)
continue;
for (rh = net_hashes[i];
}
}
}
}
}
static void
{
char buf1[INET6_ADDRSTRLEN];
static struct bits {
char *t_name;
} flagbits[] = {
/* BEGIN CSTYLED */
{ RTF_UP, "UP" },
{ RTF_GATEWAY, "GATEWAY" },
{ RTF_HOST, "HOST" },
{ 0, NULL }
/* END CSTYLED */
}, statebits[] = {
/* BEGIN CSTYLED */
{ RTS_INTERFACE, "INTERFACE" },
{ RTS_CHANGED, "CHANGED" },
{ RTS_PRIVATE, "PRIVATE" },
{ 0, NULL }
/* END CSTYLED */
};
struct bits *p;
char c;
}
c = ' ';
continue;
if (first) {
c = '|';
}
}
if (first)
c = ' ';
continue;
if (first) {
c = '|';
}
}
}
}
static void
{
int i;
for (i = IPV6_ABITS; i >= 0; i--) {
if (net_hashes[i] == NULL)
continue;
for (rh = net_hashes[i];
}
}
}
}
void
rtdump(void)
{
else
}
/*
* Create a routing socket for sending RTM_ADD and RTM_DELETE messages and
* initialize the routing socket message header and as much of the sockaddrs
* as possible.
*/
void
setup_rtsock(void)
{
char *cp;
int off = 0;
if (rtsock < 0) {
}
/* We don't want to listen to our own messages */
sizeof (off)) < 0) {
}
/*
* Allocate storage for the routing socket message.
*/
}
/*
* Initialize the routing socket message by zero-filling it and then
* setting the fields where are constant through the lifetime of the
* process.
*/
}
/*
* Initialize the constant portion of the RTA_DST sockaddr.
*/
/*
* Initialize the constant portion of the RTA_GATEWAY sockaddr.
*/
cp += sizeof (struct sockaddr_in6);
/*
* Initialize the constant portion of the RTA_NETMASK sockaddr.
*/
cp += sizeof (struct sockaddr_in6);
/*
* Initialize the constant portion of the RTA_IFP sockaddr.
*/
cp += sizeof (struct sockaddr_in6);
}