mirror of https://github.com/F-Stack/f-stack.git
Add tool: route.
This commit ports FreeBSD `route` to F-Stack, can be used to set the route table.
This commit is contained in:
parent
488adaba23
commit
144c6bcd95
|
@ -16,7 +16,7 @@ LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread
|
||||||
|
|
||||||
TARGET="helloworld"
|
TARGET="helloworld"
|
||||||
all:
|
all:
|
||||||
cc -O -gdwarf-2 -I../lib -o ${TARGET} main.c ${LIBS}
|
cc -O -gdwarf-2 -g -I../lib -o ${TARGET} main.c ${LIBS}
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -129,7 +129,8 @@ FF_SRCS+= \
|
||||||
ff_subr_prf.c \
|
ff_subr_prf.c \
|
||||||
ff_vfs_ops.c \
|
ff_vfs_ops.c \
|
||||||
ff_veth.c \
|
ff_veth.c \
|
||||||
ff_epoll.c
|
ff_epoll.c \
|
||||||
|
ff_route.c
|
||||||
|
|
||||||
FF_HOST_SRCS+= \
|
FF_HOST_SRCS+= \
|
||||||
ff_host_interface.c \
|
ff_host_interface.c \
|
||||||
|
|
29
lib/ff_api.h
29
lib/ff_api.h
|
@ -33,6 +33,7 @@ extern "C" {
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "ff_event.h"
|
#include "ff_event.h"
|
||||||
#include "ff_errno.h"
|
#include "ff_errno.h"
|
||||||
|
@ -102,6 +103,34 @@ int ff_kqueue(void);
|
||||||
int ff_kevent(int kq, const struct kevent *changelist, int nchanges,
|
int ff_kevent(int kq, const struct kevent *changelist, int nchanges,
|
||||||
struct kevent *eventlist, int nevents, const struct timespec *timeout);
|
struct kevent *eventlist, int nevents, const struct timespec *timeout);
|
||||||
|
|
||||||
|
/* route api begin */
|
||||||
|
enum FF_ROUTE_CTL {
|
||||||
|
FF_ROUTE_ADD,
|
||||||
|
FF_ROUTE_DEL,
|
||||||
|
FF_ROUTE_CHANGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FF_ROUTE_FLAG {
|
||||||
|
FF_RTF_HOST,
|
||||||
|
FF_RTF_GATEWAY,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On success, 0 is returned.
|
||||||
|
* On error, -1 is returned, and errno is set appropriately.
|
||||||
|
*/
|
||||||
|
int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag,
|
||||||
|
struct linux_sockaddr *dst, struct linux_sockaddr *gw,
|
||||||
|
struct linux_sockaddr *netmask);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is used in handling ff_msg.
|
||||||
|
* The data is a pointer to struct rt_msghdr.
|
||||||
|
*/
|
||||||
|
int ff_rtioctl(int fib, void *data, unsigned *plen, unsigned maxlen);
|
||||||
|
|
||||||
|
/* route api end */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,3 +41,5 @@ ff_mbuf_get
|
||||||
ff_mbuf_free
|
ff_mbuf_free
|
||||||
ff_mbuf_copydata
|
ff_mbuf_copydata
|
||||||
ff_mbuf_tx_offload
|
ff_mbuf_tx_offload
|
||||||
|
ff_route_ctl
|
||||||
|
ff_rtioctl
|
||||||
|
|
|
@ -721,7 +721,7 @@ init_port_start(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
|
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
|
||||||
return 0;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently, proc id 1:1 map to queue id per port. */
|
/* Currently, proc id 1:1 map to queue id per port. */
|
||||||
|
@ -852,18 +852,19 @@ ff_veth_input(const struct ff_dpdk_if_context *ctx, struct rte_mbuf *pkt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt = pkt->next;
|
struct rte_mbuf *pn = pkt->next;
|
||||||
void *prev = hdr;
|
void *prev = hdr;
|
||||||
while(pkt != NULL) {
|
while(pn != NULL) {
|
||||||
data = rte_pktmbuf_mtod(pkt, void*);
|
data = rte_pktmbuf_mtod(pkt, void*);
|
||||||
len = rte_pktmbuf_data_len(pkt);
|
len = rte_pktmbuf_data_len(pkt);
|
||||||
|
|
||||||
void *mb = ff_mbuf_get(prev, data, len);
|
void *mb = ff_mbuf_get(prev, data, len);
|
||||||
if (mb == NULL) {
|
if (mb == NULL) {
|
||||||
ff_mbuf_free(hdr);
|
ff_mbuf_free(hdr);
|
||||||
|
rte_pktmbuf_free(pkt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pkt = pkt->next;
|
pn = pn->next;
|
||||||
prev = mb;
|
prev = mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,6 +1005,15 @@ done:
|
||||||
rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
|
rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
handle_route_msg(struct ff_msg *msg, uint16_t proc_id)
|
||||||
|
{
|
||||||
|
msg->result = ff_rtioctl(msg->route.fib, msg->route.data,
|
||||||
|
&msg->route.len, msg->route.maxlen);
|
||||||
|
|
||||||
|
rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
handle_default_msg(struct ff_msg *msg, uint16_t proc_id)
|
handle_default_msg(struct ff_msg *msg, uint16_t proc_id)
|
||||||
{
|
{
|
||||||
|
@ -1021,6 +1031,9 @@ handle_msg(struct ff_msg *msg, uint16_t proc_id)
|
||||||
case FF_IOCTL:
|
case FF_IOCTL:
|
||||||
handle_ioctl_msg(msg, proc_id);
|
handle_ioctl_msg(msg, proc_id);
|
||||||
break;
|
break;
|
||||||
|
case FF_ROUTE:
|
||||||
|
handle_route_msg(msg, proc_id);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
handle_default_msg(msg, proc_id);
|
handle_default_msg(msg, proc_id);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -38,6 +38,7 @@ enum FF_MSG_TYPE {
|
||||||
FF_UNKNOWN = 0,
|
FF_UNKNOWN = 0,
|
||||||
FF_SYSCTL,
|
FF_SYSCTL,
|
||||||
FF_IOCTL,
|
FF_IOCTL,
|
||||||
|
FF_ROUTE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ff_sysctl_args {
|
struct ff_sysctl_args {
|
||||||
|
@ -54,6 +55,13 @@ struct ff_ioctl_args {
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ff_route_args {
|
||||||
|
int fib;
|
||||||
|
unsigned len;
|
||||||
|
unsigned maxlen;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_MSG_BUF_SIZE 10240
|
#define MAX_MSG_BUF_SIZE 10240
|
||||||
|
|
||||||
/* structure of ipc msg */
|
/* structure of ipc msg */
|
||||||
|
@ -69,6 +77,7 @@ struct ff_msg {
|
||||||
union {
|
union {
|
||||||
struct ff_sysctl_args sysctl;
|
struct ff_sysctl_args sysctl;
|
||||||
struct ff_ioctl_args ioctl;
|
struct ff_ioctl_args ioctl;
|
||||||
|
struct ff_route_args route;
|
||||||
};
|
};
|
||||||
} __attribute__((packed)) __rte_cache_aligned;
|
} __attribute__((packed)) __rte_cache_aligned;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,733 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1988, 1991, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
* Copyright (C) 2017 THL A29 Limited, a Tencent company.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Copied part from FreeBSD rtsock.c.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/jail.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/domain.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/socketvar.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_var.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if_llatbl.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <net/route_var.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
#include "ff_api.h"
|
||||||
|
#include "ff_host_interface.h"
|
||||||
|
|
||||||
|
#ifndef _SOCKADDR_UNION_DEFINED
|
||||||
|
#define _SOCKADDR_UNION_DEFINED
|
||||||
|
/*
|
||||||
|
* The union of all possible address formats we handle.
|
||||||
|
*/
|
||||||
|
union sockaddr_union {
|
||||||
|
struct sockaddr sa;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
struct sockaddr_in6 sin6;
|
||||||
|
};
|
||||||
|
#endif /* _SOCKADDR_UNION_DEFINED */
|
||||||
|
|
||||||
|
static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, };
|
||||||
|
|
||||||
|
struct walkarg {
|
||||||
|
int w_tmemsize;
|
||||||
|
int w_op, w_arg;
|
||||||
|
caddr_t w_tmem;
|
||||||
|
struct sysctl_req *w_req;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
|
||||||
|
struct rtentry *rt, union sockaddr_union *saun, struct ucred *cred)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* First, see if the returned address is part of the jail. */
|
||||||
|
if (prison_if(cred, rt->rt_ifa->ifa_addr) == 0) {
|
||||||
|
info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (info->rti_info[RTAX_DST]->sa_family) {
|
||||||
|
#ifdef INET
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct in_addr ia;
|
||||||
|
struct ifaddr *ifa;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
/*
|
||||||
|
* Try to find an address on the given outgoing interface
|
||||||
|
* that belongs to the jail.
|
||||||
|
*/
|
||||||
|
IF_ADDR_RLOCK(ifp);
|
||||||
|
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||||
|
struct sockaddr *sa;
|
||||||
|
sa = ifa->ifa_addr;
|
||||||
|
if (sa->sa_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
ia = ((struct sockaddr_in *)sa)->sin_addr;
|
||||||
|
if (prison_check_ip4(cred, &ia) == 0) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IF_ADDR_RUNLOCK(ifp);
|
||||||
|
if (!found) {
|
||||||
|
/*
|
||||||
|
* As a last resort return the 'default' jail address.
|
||||||
|
*/
|
||||||
|
ia = ((struct sockaddr_in *)rt->rt_ifa->ifa_addr)->
|
||||||
|
sin_addr;
|
||||||
|
if (prison_get_ip4(cred, &ia) != 0)
|
||||||
|
return (ESRCH);
|
||||||
|
}
|
||||||
|
bzero(&saun->sin, sizeof(struct sockaddr_in));
|
||||||
|
saun->sin.sin_len = sizeof(struct sockaddr_in);
|
||||||
|
saun->sin.sin_family = AF_INET;
|
||||||
|
saun->sin.sin_addr.s_addr = ia.s_addr;
|
||||||
|
info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef INET6
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct in6_addr ia6;
|
||||||
|
struct ifaddr *ifa;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
/*
|
||||||
|
* Try to find an address on the given outgoing interface
|
||||||
|
* that belongs to the jail.
|
||||||
|
*/
|
||||||
|
IF_ADDR_RLOCK(ifp);
|
||||||
|
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||||
|
struct sockaddr *sa;
|
||||||
|
sa = ifa->ifa_addr;
|
||||||
|
if (sa->sa_family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
|
||||||
|
&ia6, sizeof(struct in6_addr));
|
||||||
|
if (prison_check_ip6(cred, &ia6) == 0) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IF_ADDR_RUNLOCK(ifp);
|
||||||
|
if (!found) {
|
||||||
|
/*
|
||||||
|
* As a last resort return the 'default' jail address.
|
||||||
|
*/
|
||||||
|
ia6 = ((struct sockaddr_in6 *)rt->rt_ifa->ifa_addr)->
|
||||||
|
sin6_addr;
|
||||||
|
if (prison_get_ip6(cred, &ia6) != 0)
|
||||||
|
return (ESRCH);
|
||||||
|
}
|
||||||
|
bzero(&saun->sin6, sizeof(struct sockaddr_in6));
|
||||||
|
saun->sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||||
|
saun->sin6.sin6_family = AF_INET6;
|
||||||
|
bcopy(&ia6, &saun->sin6.sin6_addr, sizeof(struct in6_addr));
|
||||||
|
if (sa6_recoverscope(&saun->sin6) != 0)
|
||||||
|
return (ESRCH);
|
||||||
|
info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return (ESRCH);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the addresses of the passed sockaddrs.
|
||||||
|
* Do a little sanity checking so as to avoid bad memory references.
|
||||||
|
* This data is derived straight from userland.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
|
||||||
|
{
|
||||||
|
struct sockaddr *sa;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
|
||||||
|
if ((rtinfo->rti_addrs & (1 << i)) == 0)
|
||||||
|
continue;
|
||||||
|
sa = (struct sockaddr *)cp;
|
||||||
|
/*
|
||||||
|
* It won't fit.
|
||||||
|
*/
|
||||||
|
if (cp + sa->sa_len > cplim)
|
||||||
|
return (EINVAL);
|
||||||
|
/*
|
||||||
|
* there are no more.. quit now
|
||||||
|
* If there are more bits, they are in error.
|
||||||
|
* I've seen this. route(1) can evidently generate these.
|
||||||
|
* This causes kernel to core dump.
|
||||||
|
* for compatibility, If we see this, point to a safe address.
|
||||||
|
*/
|
||||||
|
if (sa->sa_len == 0) {
|
||||||
|
rtinfo->rti_info[i] = &sa_zero;
|
||||||
|
return (0); /* should be EINVAL but for compat */
|
||||||
|
}
|
||||||
|
/* accept it */
|
||||||
|
#ifdef INET6
|
||||||
|
if (sa->sa_family == AF_INET6)
|
||||||
|
sa6_embedscope((struct sockaddr_in6 *)sa,
|
||||||
|
V_ip6_use_defzone);
|
||||||
|
#endif
|
||||||
|
rtinfo->rti_info[i] = sa;
|
||||||
|
cp += SA_SIZE(sa);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes information related to @rtinfo object to preallocated buffer.
|
||||||
|
* Stores needed size in @plen. If @w is NULL, calculates size without
|
||||||
|
* writing.
|
||||||
|
* Used for sysctl dumps and rtsock answers (RTM_DEL/RTM_GET) generation.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *plen)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len, buflen = 0, dlen;
|
||||||
|
caddr_t cp = NULL;
|
||||||
|
struct rt_msghdr *rtm = NULL;
|
||||||
|
#ifdef INET6
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
|
||||||
|
case RTM_DELADDR:
|
||||||
|
case RTM_NEWADDR:
|
||||||
|
if (w != NULL && w->w_op == NET_RT_IFLISTL) {
|
||||||
|
#ifdef COMPAT_FREEBSD32
|
||||||
|
if (w->w_req->flags & SCTL_MASK32)
|
||||||
|
len = sizeof(struct ifa_msghdrl32);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
len = sizeof(struct ifa_msghdrl);
|
||||||
|
} else
|
||||||
|
len = sizeof(struct ifa_msghdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_IFINFO:
|
||||||
|
#ifdef COMPAT_FREEBSD32
|
||||||
|
if (w != NULL && w->w_req->flags & SCTL_MASK32) {
|
||||||
|
if (w->w_op == NET_RT_IFLISTL)
|
||||||
|
len = sizeof(struct if_msghdrl32);
|
||||||
|
else
|
||||||
|
len = sizeof(struct if_msghdr32);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (w != NULL && w->w_op == NET_RT_IFLISTL)
|
||||||
|
len = sizeof(struct if_msghdrl);
|
||||||
|
else
|
||||||
|
len = sizeof(struct if_msghdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_NEWMADDR:
|
||||||
|
len = sizeof(struct ifma_msghdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
len = sizeof(struct rt_msghdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w != NULL) {
|
||||||
|
rtm = (struct rt_msghdr *)w->w_tmem;
|
||||||
|
buflen = w->w_tmemsize - len;
|
||||||
|
cp = (caddr_t)w->w_tmem + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtinfo->rti_addrs = 0;
|
||||||
|
for (i = 0; i < RTAX_MAX; i++) {
|
||||||
|
struct sockaddr *sa;
|
||||||
|
|
||||||
|
if ((sa = rtinfo->rti_info[i]) == NULL)
|
||||||
|
continue;
|
||||||
|
rtinfo->rti_addrs |= (1 << i);
|
||||||
|
dlen = SA_SIZE(sa);
|
||||||
|
if (cp != NULL && buflen >= dlen) {
|
||||||
|
#ifdef INET6
|
||||||
|
if (V_deembed_scopeid && sa->sa_family == AF_INET6) {
|
||||||
|
sin6 = (struct sockaddr_in6 *)&ss;
|
||||||
|
bcopy(sa, sin6, sizeof(*sin6));
|
||||||
|
if (sa6_recoverscope(sin6) == 0)
|
||||||
|
sa = (struct sockaddr *)sin6;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bcopy((caddr_t)sa, cp, (unsigned)dlen);
|
||||||
|
cp += dlen;
|
||||||
|
buflen -= dlen;
|
||||||
|
} else if (cp != NULL) {
|
||||||
|
/*
|
||||||
|
* Buffer too small. Count needed size
|
||||||
|
* and return with error.
|
||||||
|
*/
|
||||||
|
cp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += dlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp != NULL) {
|
||||||
|
dlen = ALIGN(len) - len;
|
||||||
|
if (buflen < dlen)
|
||||||
|
cp = NULL;
|
||||||
|
else
|
||||||
|
buflen -= dlen;
|
||||||
|
}
|
||||||
|
len = ALIGN(len);
|
||||||
|
|
||||||
|
if (cp != NULL) {
|
||||||
|
/* fill header iff buffer is large enough */
|
||||||
|
rtm->rtm_version = RTM_VERSION;
|
||||||
|
rtm->rtm_type = type;
|
||||||
|
rtm->rtm_msglen = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
*plen = len;
|
||||||
|
|
||||||
|
if (w != NULL && cp == NULL)
|
||||||
|
return (ENOBUFS);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in @dmask with valid netmask leaving original @smask
|
||||||
|
* intact. Mostly used with radix netmasks.
|
||||||
|
*/
|
||||||
|
static struct sockaddr *
|
||||||
|
rtsock_fix_netmask(struct sockaddr *dst, struct sockaddr *smask,
|
||||||
|
struct sockaddr_storage *dmask)
|
||||||
|
{
|
||||||
|
if (dst == NULL || smask == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
memset(dmask, 0, dst->sa_len);
|
||||||
|
memcpy(dmask, smask, smask->sa_len);
|
||||||
|
dmask->ss_len = dst->sa_len;
|
||||||
|
dmask->ss_family = dst->sa_family;
|
||||||
|
|
||||||
|
return ((struct sockaddr *)dmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out)
|
||||||
|
{
|
||||||
|
|
||||||
|
bzero(out, sizeof(*out));
|
||||||
|
out->rmx_mtu = rt->rt_mtu;
|
||||||
|
out->rmx_weight = rt->rt_weight;
|
||||||
|
out->rmx_pksent = counter_u64_fetch(rt->rt_pksent);
|
||||||
|
/* Kernel -> userland timebase conversion. */
|
||||||
|
out->rmx_expire = rt->rt_expire ?
|
||||||
|
rt->rt_expire - time_uptime + time_second : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ff_rtioctl(int fibnum, void *data, unsigned *plen, unsigned maxlen)
|
||||||
|
{
|
||||||
|
struct rt_msghdr *rtm = NULL;
|
||||||
|
struct rtentry *rt = NULL;
|
||||||
|
struct rib_head *rnh;
|
||||||
|
struct rt_addrinfo info;
|
||||||
|
union sockaddr_union saun;
|
||||||
|
sa_family_t saf = AF_UNSPEC;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
struct walkarg w;
|
||||||
|
int error = 0, alloc_len = 0, len;
|
||||||
|
struct ifnet *ifp = NULL;
|
||||||
|
|
||||||
|
#ifdef INET6
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
int i, rti_need_deembed = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define senderr(e) { error = e; goto flush;}
|
||||||
|
|
||||||
|
len = *plen;
|
||||||
|
/*
|
||||||
|
* Most of current messages are in range 200-240 bytes,
|
||||||
|
* minimize possible re-allocation on reply using larger size
|
||||||
|
* buffer aligned on 1k boundaty.
|
||||||
|
*/
|
||||||
|
alloc_len = roundup2(len, 1024);
|
||||||
|
if ((rtm = malloc(alloc_len, M_TEMP, M_NOWAIT)) == NULL)
|
||||||
|
senderr(ENOBUFS);
|
||||||
|
bcopy(data, (caddr_t)rtm, len);
|
||||||
|
|
||||||
|
if (len < sizeof(*rtm) || len != rtm->rtm_msglen)
|
||||||
|
senderr(EINVAL);
|
||||||
|
|
||||||
|
bzero(&info, sizeof(info));
|
||||||
|
bzero(&w, sizeof(w));
|
||||||
|
|
||||||
|
if (rtm->rtm_version != RTM_VERSION)
|
||||||
|
senderr(EPROTONOSUPPORT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Starting from here, it is possible
|
||||||
|
* to alter original message and insert
|
||||||
|
* caller PID and error value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtm->rtm_pid = curproc->p_pid;
|
||||||
|
info.rti_addrs = rtm->rtm_addrs;
|
||||||
|
|
||||||
|
info.rti_mflags = rtm->rtm_inits;
|
||||||
|
info.rti_rmx = &rtm->rtm_rmx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rt_xaddrs() performs s6_addr[2] := sin6_scope_id for AF_INET6
|
||||||
|
* link-local address because rtrequest requires addresses with
|
||||||
|
* embedded scope id.
|
||||||
|
*/
|
||||||
|
if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info))
|
||||||
|
senderr(EINVAL);
|
||||||
|
|
||||||
|
info.rti_flags = rtm->rtm_flags;
|
||||||
|
if (info.rti_info[RTAX_DST] == NULL ||
|
||||||
|
info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
|
||||||
|
(info.rti_info[RTAX_GATEWAY] != NULL &&
|
||||||
|
info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX))
|
||||||
|
senderr(EINVAL);
|
||||||
|
saf = info.rti_info[RTAX_DST]->sa_family;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The given gateway address may be an interface address.
|
||||||
|
* For example, issuing a "route change" command on a route
|
||||||
|
* entry that was created from a tunnel, and the gateway
|
||||||
|
* address given is the local end point. In this case the
|
||||||
|
* RTF_GATEWAY flag must be cleared or the destination will
|
||||||
|
* not be reachable even though there is no error message.
|
||||||
|
*/
|
||||||
|
if (info.rti_info[RTAX_GATEWAY] != NULL &&
|
||||||
|
info.rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) {
|
||||||
|
struct rt_addrinfo ginfo;
|
||||||
|
struct sockaddr *gdst;
|
||||||
|
|
||||||
|
bzero(&ginfo, sizeof(ginfo));
|
||||||
|
bzero(&ss, sizeof(ss));
|
||||||
|
ss.ss_len = sizeof(ss);
|
||||||
|
|
||||||
|
ginfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&ss;
|
||||||
|
gdst = info.rti_info[RTAX_GATEWAY];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A host route through the loopback interface is
|
||||||
|
* installed for each interface adddress. In pre 8.0
|
||||||
|
* releases the interface address of a PPP link type
|
||||||
|
* is not reachable locally. This behavior is fixed as
|
||||||
|
* part of the new L2/L3 redesign and rewrite work. The
|
||||||
|
* signature of this interface address route is the
|
||||||
|
* AF_LINK sa_family type of the rt_gateway, and the
|
||||||
|
* rt_ifp has the IFF_LOOPBACK flag set.
|
||||||
|
*/
|
||||||
|
if (rib_lookup_info(fibnum, gdst, NHR_REF, 0, &ginfo) == 0) {
|
||||||
|
if (ss.ss_family == AF_LINK &&
|
||||||
|
ginfo.rti_ifp->if_flags & IFF_LOOPBACK) {
|
||||||
|
info.rti_flags &= ~RTF_GATEWAY;
|
||||||
|
info.rti_flags |= RTF_GWFLAG_COMPAT;
|
||||||
|
}
|
||||||
|
rib_free_info(&ginfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rtm->rtm_type) {
|
||||||
|
struct rtentry *saved_nrt;
|
||||||
|
|
||||||
|
case RTM_ADD:
|
||||||
|
case RTM_CHANGE:
|
||||||
|
if (info.rti_info[RTAX_GATEWAY] == NULL)
|
||||||
|
senderr(EINVAL);
|
||||||
|
saved_nrt = NULL;
|
||||||
|
|
||||||
|
/* support for new ARP code */
|
||||||
|
if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK &&
|
||||||
|
(rtm->rtm_flags & RTF_LLDATA) != 0) {
|
||||||
|
error = lla_rt_output(rtm, &info);
|
||||||
|
#ifdef INET6
|
||||||
|
if (error == 0)
|
||||||
|
rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error = rtrequest1_fib(rtm->rtm_type, &info, &saved_nrt,
|
||||||
|
fibnum);
|
||||||
|
if (error == 0 && saved_nrt != NULL) {
|
||||||
|
#ifdef INET6
|
||||||
|
rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
RT_LOCK(saved_nrt);
|
||||||
|
rtm->rtm_index = saved_nrt->rt_ifp->if_index;
|
||||||
|
RT_REMREF(saved_nrt);
|
||||||
|
RT_UNLOCK(saved_nrt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_DELETE:
|
||||||
|
saved_nrt = NULL;
|
||||||
|
/* support for new ARP code */
|
||||||
|
if (info.rti_info[RTAX_GATEWAY] &&
|
||||||
|
(info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) &&
|
||||||
|
(rtm->rtm_flags & RTF_LLDATA) != 0) {
|
||||||
|
error = lla_rt_output(rtm, &info);
|
||||||
|
#ifdef INET6
|
||||||
|
if (error == 0)
|
||||||
|
rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, fibnum);
|
||||||
|
if (error == 0) {
|
||||||
|
RT_LOCK(saved_nrt);
|
||||||
|
rt = saved_nrt;
|
||||||
|
goto report;
|
||||||
|
}
|
||||||
|
#ifdef INET6
|
||||||
|
/* rt_msg2() will not be used when RTM_DELETE fails. */
|
||||||
|
rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_GET:
|
||||||
|
rnh = rt_tables_get_rnh(fibnum, saf);
|
||||||
|
if (rnh == NULL)
|
||||||
|
senderr(EAFNOSUPPORT);
|
||||||
|
|
||||||
|
RIB_RLOCK(rnh);
|
||||||
|
|
||||||
|
if (info.rti_info[RTAX_NETMASK] == NULL &&
|
||||||
|
rtm->rtm_type == RTM_GET) {
|
||||||
|
/*
|
||||||
|
* Provide logest prefix match for
|
||||||
|
* address lookup (no mask).
|
||||||
|
* 'route -n get addr'
|
||||||
|
*/
|
||||||
|
rt = (struct rtentry *) rnh->rnh_matchaddr(
|
||||||
|
info.rti_info[RTAX_DST], &rnh->head);
|
||||||
|
} else
|
||||||
|
rt = (struct rtentry *) rnh->rnh_lookup(
|
||||||
|
info.rti_info[RTAX_DST],
|
||||||
|
info.rti_info[RTAX_NETMASK], &rnh->head);
|
||||||
|
|
||||||
|
if (rt == NULL) {
|
||||||
|
RIB_RUNLOCK(rnh);
|
||||||
|
senderr(ESRCH);
|
||||||
|
}
|
||||||
|
#ifdef RADIX_MPATH
|
||||||
|
/*
|
||||||
|
* for RTM_CHANGE/LOCK, if we got multipath routes,
|
||||||
|
* we require users to specify a matching RTAX_GATEWAY.
|
||||||
|
*
|
||||||
|
* for RTM_GET, gate is optional even with multipath.
|
||||||
|
* if gate == NULL the first match is returned.
|
||||||
|
* (no need to call rt_mpath_matchgate if gate == NULL)
|
||||||
|
*/
|
||||||
|
if (rt_mpath_capable(rnh) &&
|
||||||
|
(rtm->rtm_type != RTM_GET || info.rti_info[RTAX_GATEWAY])) {
|
||||||
|
rt = rt_mpath_matchgate(rt, info.rti_info[RTAX_GATEWAY]);
|
||||||
|
if (!rt) {
|
||||||
|
RIB_RUNLOCK(rnh);
|
||||||
|
senderr(ESRCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* If performing proxied L2 entry insertion, and
|
||||||
|
* the actual PPP host entry is found, perform
|
||||||
|
* another search to retrieve the prefix route of
|
||||||
|
* the local end point of the PPP link.
|
||||||
|
*/
|
||||||
|
if (rtm->rtm_flags & RTF_ANNOUNCE) {
|
||||||
|
struct sockaddr laddr;
|
||||||
|
|
||||||
|
if (rt->rt_ifp != NULL &&
|
||||||
|
rt->rt_ifp->if_type == IFT_PROPVIRTUAL) {
|
||||||
|
struct ifaddr *ifa;
|
||||||
|
|
||||||
|
ifa = ifa_ifwithnet(info.rti_info[RTAX_DST], 1,
|
||||||
|
RT_ALL_FIBS);
|
||||||
|
if (ifa != NULL)
|
||||||
|
rt_maskedcopy(ifa->ifa_addr,
|
||||||
|
&laddr,
|
||||||
|
ifa->ifa_netmask);
|
||||||
|
} else
|
||||||
|
rt_maskedcopy(rt->rt_ifa->ifa_addr,
|
||||||
|
&laddr,
|
||||||
|
rt->rt_ifa->ifa_netmask);
|
||||||
|
/*
|
||||||
|
* refactor rt and no lock operation necessary
|
||||||
|
*/
|
||||||
|
rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr,
|
||||||
|
&rnh->head);
|
||||||
|
if (rt == NULL) {
|
||||||
|
RIB_RUNLOCK(rnh);
|
||||||
|
senderr(ESRCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RT_LOCK(rt);
|
||||||
|
RT_ADDREF(rt);
|
||||||
|
RIB_RUNLOCK(rnh);
|
||||||
|
|
||||||
|
report:
|
||||||
|
RT_LOCK_ASSERT(rt);
|
||||||
|
if ((rt->rt_flags & RTF_HOST) == 0
|
||||||
|
? jailed_without_vnet(curthread->td_ucred)
|
||||||
|
: prison_if(curthread->td_ucred,
|
||||||
|
rt_key(rt)) != 0) {
|
||||||
|
RT_UNLOCK(rt);
|
||||||
|
senderr(ESRCH);
|
||||||
|
}
|
||||||
|
info.rti_info[RTAX_DST] = rt_key(rt);
|
||||||
|
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
|
||||||
|
info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt),
|
||||||
|
rt_mask(rt), &ss);
|
||||||
|
info.rti_info[RTAX_GENMASK] = 0;
|
||||||
|
if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
|
||||||
|
ifp = rt->rt_ifp;
|
||||||
|
if (ifp) {
|
||||||
|
info.rti_info[RTAX_IFP] =
|
||||||
|
ifp->if_addr->ifa_addr;
|
||||||
|
error = rtm_get_jailed(&info, ifp, rt,
|
||||||
|
&saun, curthread->td_ucred);
|
||||||
|
if (error != 0) {
|
||||||
|
RT_UNLOCK(rt);
|
||||||
|
senderr(error);
|
||||||
|
}
|
||||||
|
if (ifp->if_flags & IFF_POINTOPOINT)
|
||||||
|
info.rti_info[RTAX_BRD] =
|
||||||
|
rt->rt_ifa->ifa_dstaddr;
|
||||||
|
rtm->rtm_index = ifp->if_index;
|
||||||
|
} else {
|
||||||
|
info.rti_info[RTAX_IFP] = NULL;
|
||||||
|
info.rti_info[RTAX_IFA] = NULL;
|
||||||
|
}
|
||||||
|
} else if ((ifp = rt->rt_ifp) != NULL) {
|
||||||
|
rtm->rtm_index = ifp->if_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we need to realloc storage */
|
||||||
|
rtsock_msg_buffer(rtm->rtm_type, &info, NULL, &len);
|
||||||
|
if (len > maxlen) {
|
||||||
|
RT_UNLOCK(rt);
|
||||||
|
senderr(ENOBUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > alloc_len) {
|
||||||
|
struct rt_msghdr *new_rtm;
|
||||||
|
new_rtm = malloc(len, M_TEMP, M_NOWAIT);
|
||||||
|
if (new_rtm == NULL) {
|
||||||
|
RT_UNLOCK(rt);
|
||||||
|
senderr(ENOBUFS);
|
||||||
|
}
|
||||||
|
bcopy(rtm, new_rtm, rtm->rtm_msglen);
|
||||||
|
free(rtm, M_TEMP);
|
||||||
|
rtm = new_rtm;
|
||||||
|
alloc_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
w.w_tmem = (caddr_t)rtm;
|
||||||
|
w.w_tmemsize = alloc_len;
|
||||||
|
rtsock_msg_buffer(rtm->rtm_type, &info, &w, &len);
|
||||||
|
|
||||||
|
if (rt->rt_flags & RTF_GWFLAG_COMPAT)
|
||||||
|
rtm->rtm_flags = RTF_GATEWAY |
|
||||||
|
(rt->rt_flags & ~RTF_GWFLAG_COMPAT);
|
||||||
|
else
|
||||||
|
rtm->rtm_flags = rt->rt_flags;
|
||||||
|
rt_getmetrics(rt, &rtm->rtm_rmx);
|
||||||
|
rtm->rtm_addrs = info.rti_addrs;
|
||||||
|
|
||||||
|
RT_UNLOCK(rt);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
senderr(EOPNOTSUPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
flush:
|
||||||
|
if (rt != NULL)
|
||||||
|
RTFREE(rt);
|
||||||
|
|
||||||
|
if (rtm != NULL) {
|
||||||
|
#ifdef INET6
|
||||||
|
if (rti_need_deembed) {
|
||||||
|
/* sin6_scope_id is recovered before sending rtm. */
|
||||||
|
sin6 = (struct sockaddr_in6 *)&ss;
|
||||||
|
for (i = 0; i < RTAX_MAX; i++) {
|
||||||
|
if (info.rti_info[i] == NULL)
|
||||||
|
continue;
|
||||||
|
if (info.rti_info[i]->sa_family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
bcopy(info.rti_info[i], sin6, sizeof(*sin6));
|
||||||
|
if (sa6_recoverscope(sin6) == 0)
|
||||||
|
bcopy(sin6, info.rti_info[i],
|
||||||
|
sizeof(*sin6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (error != 0)
|
||||||
|
rtm->rtm_errno = error;
|
||||||
|
else
|
||||||
|
rtm->rtm_flags |= RTF_DONE;
|
||||||
|
|
||||||
|
bcopy((caddr_t)rtm, data, rtm->rtm_msglen);
|
||||||
|
*plen = rtm->rtm_msglen;
|
||||||
|
free(rtm, M_TEMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
|
@ -50,6 +50,7 @@
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#include <sys/sysproto.h>
|
#include <sys/sysproto.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.h>
|
||||||
|
|
||||||
|
@ -258,7 +259,7 @@ so_opt_convert(int optname)
|
||||||
case LINUX_SO_PROTOCOL:
|
case LINUX_SO_PROTOCOL:
|
||||||
return SO_PROTOCOL;
|
return SO_PROTOCOL;
|
||||||
default:
|
default:
|
||||||
return (-1);
|
return optname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +286,7 @@ ip_opt_convert(int optname)
|
||||||
case LINUX_IP_DROP_MEMBERSHIP:
|
case LINUX_IP_DROP_MEMBERSHIP:
|
||||||
return IP_DROP_MEMBERSHIP;
|
return IP_DROP_MEMBERSHIP;
|
||||||
default:
|
default:
|
||||||
return (-1);
|
return optname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +307,7 @@ tcp_opt_convert(int optname)
|
||||||
case LINUX_TCP_MD5SIG:
|
case LINUX_TCP_MD5SIG:
|
||||||
return TCP_MD5SIG;
|
return TCP_MD5SIG;
|
||||||
default:
|
default:
|
||||||
return (-1);
|
return optname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +322,7 @@ linux2freebsd_opt(int level, int optname)
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
return tcp_opt_convert(optname);
|
return tcp_opt_convert(optname);
|
||||||
default:
|
default:
|
||||||
return (-1);
|
return optname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1002,3 +1003,76 @@ kern_fail:
|
||||||
ff_os_errno(rc);
|
ff_os_errno(rc);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag,
|
||||||
|
struct linux_sockaddr *dst, struct linux_sockaddr *gw,
|
||||||
|
struct linux_sockaddr *netmask)
|
||||||
|
|
||||||
|
{
|
||||||
|
struct sockaddr sa_gw, sa_dst, sa_nm;
|
||||||
|
struct sockaddr *psa_gw, *psa_dst, *psa_nm;
|
||||||
|
int rtreq, rtflag;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
switch (req) {
|
||||||
|
case FF_ROUTE_ADD:
|
||||||
|
rtreq = RTM_ADD;
|
||||||
|
break;
|
||||||
|
case FF_ROUTE_DEL:
|
||||||
|
rtreq = RTM_DELETE;
|
||||||
|
break;
|
||||||
|
case FF_ROUTE_CHANGE:
|
||||||
|
rtreq = RTM_CHANGE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = EINVAL;
|
||||||
|
goto kern_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case FF_RTF_HOST:
|
||||||
|
rtflag = RTF_HOST;
|
||||||
|
break;
|
||||||
|
case FF_RTF_GATEWAY:
|
||||||
|
rtflag = RTF_GATEWAY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = EINVAL;
|
||||||
|
goto kern_fail;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (gw != NULL) {
|
||||||
|
psa_gw = &sa_gw;
|
||||||
|
linux2freebsd_sockaddr(gw, sizeof(*gw), psa_gw);
|
||||||
|
} else {
|
||||||
|
psa_gw = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst != NULL) {
|
||||||
|
psa_dst = &sa_dst;
|
||||||
|
linux2freebsd_sockaddr(dst, sizeof(*dst), psa_dst);
|
||||||
|
} else {
|
||||||
|
psa_dst = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netmask != NULL) {
|
||||||
|
psa_nm = &sa_nm;
|
||||||
|
linux2freebsd_sockaddr(netmask, sizeof(*netmask), psa_nm);
|
||||||
|
} else {
|
||||||
|
psa_nm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = rtrequest_fib(rtreq, psa_dst, psa_gw, psa_nm, rtflag,
|
||||||
|
NULL, RT_DEFAULT_FIB);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
goto kern_fail;
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
|
||||||
|
kern_fail:
|
||||||
|
ff_os_errno(rc);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS=compat sysctl ifconfig
|
SUBDIRS=compat sysctl ifconfig route
|
||||||
|
|
||||||
all:
|
all:
|
||||||
for d in $(SUBDIRS); do ( cd $$d; $(MAKE) all ) ; done
|
for d in $(SUBDIRS); do ( cd $$d; $(MAKE) all ) ; done
|
||||||
|
|
|
@ -39,6 +39,52 @@ jail
|
||||||
```
|
```
|
||||||
For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?ifconfig).
|
For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?ifconfig).
|
||||||
|
|
||||||
|
# route
|
||||||
|
Usage:
|
||||||
|
```
|
||||||
|
route -p <f-stack proc_id> [-46dnqtv] command [[modifiers] args]
|
||||||
|
```
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
Add a default route:
|
||||||
|
|
||||||
|
./route -p 0 add -net 0.0.0.0/0 192.168.1.1
|
||||||
|
|
||||||
|
A shorter version of adding a default route can also be written as:
|
||||||
|
|
||||||
|
./route -p 0 add default 192.168.1.1
|
||||||
|
|
||||||
|
Add a static route to the 172.16.10.0/24 network via the 172.16.1.1 gate-
|
||||||
|
way:
|
||||||
|
|
||||||
|
./route -p 0 add -net 172.16.10.0/24 172.16.1.1
|
||||||
|
|
||||||
|
Change the gateway of an already established static route in the routing
|
||||||
|
table:
|
||||||
|
|
||||||
|
./route -p 0 change -net 172.16.10.0/24 172.16.1.2
|
||||||
|
|
||||||
|
Display the route for a destination network:
|
||||||
|
|
||||||
|
./route -p 0 show 172.16.10.0
|
||||||
|
|
||||||
|
Delete a static route from the routing table:
|
||||||
|
|
||||||
|
./route -p 0 delete -net 172.16.10.0/24 172.16.1.2
|
||||||
|
|
||||||
|
Remove all routes from the routing table:
|
||||||
|
|
||||||
|
./route -p 0 flush
|
||||||
|
|
||||||
|
FreeBSD uses `netstat -rn ` to list the route table which we havn't ported,
|
||||||
|
you can execute the following command instead, `-d` means debug mode, `-v`
|
||||||
|
means verbose.
|
||||||
|
./route -p 0 -d -v flush
|
||||||
|
```
|
||||||
|
Note that, if you want to modify the route table, you must use `-p` to execute the same command for each f-stack process.
|
||||||
|
|
||||||
|
For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?route).
|
||||||
|
|
||||||
# how to implement a custom tool for communicating with F-Stack process
|
# how to implement a custom tool for communicating with F-Stack process
|
||||||
|
|
||||||
Add a new FF_MSG_TYPE in ff_msg.h:
|
Add a new FF_MSG_TYPE in ff_msg.h:
|
||||||
|
|
|
@ -29,6 +29,22 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef __dead2
|
||||||
|
#define __dead2 __attribute__((__noreturn__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __dead
|
||||||
|
#define __dead __dead2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef nitems
|
||||||
|
#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __FBSDID
|
||||||
|
#define __FBSDID(s) /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
void *reallocf(void *ptr, size_t size);
|
void *reallocf(void *ptr, size_t size);
|
||||||
|
|
||||||
int feature_present(const char *feature);
|
int feature_present(const char *feature);
|
||||||
|
|
|
@ -61,7 +61,7 @@ ff_ipc_init(void)
|
||||||
char *dpdk_argv[] = {
|
char *dpdk_argv[] = {
|
||||||
"ff-ipc", "-c1", "-n4",
|
"ff-ipc", "-c1", "-n4",
|
||||||
"--proc-type=secondary",
|
"--proc-type=secondary",
|
||||||
/* RTE_LOG_ERR */
|
/* RTE_LOG_WARNING */
|
||||||
"--log-level=5",
|
"--log-level=5",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1987, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef FSTACK
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include "namespace.h"
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifndef FSTACK
|
||||||
|
#include "un-namespace.h"
|
||||||
|
|
||||||
|
#include "libc_private.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int opterr = 1, /* if error message should be printed */
|
||||||
|
optind = 1, /* index into parent argv vector */
|
||||||
|
optopt, /* character checked for validity */
|
||||||
|
optreset; /* reset getopt */
|
||||||
|
char *optarg; /* argument associated with option */
|
||||||
|
|
||||||
|
#define BADCH (int)'?'
|
||||||
|
#define BADARG (int)':'
|
||||||
|
#define EMSG ""
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getopt --
|
||||||
|
* Parse argc/argv argument vector.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
getopt(int nargc, char * const nargv[], const char *ostr)
|
||||||
|
{
|
||||||
|
static char *place = EMSG; /* option letter processing */
|
||||||
|
char *oli; /* option letter list index */
|
||||||
|
|
||||||
|
if (optreset || *place == 0) { /* update scanning pointer */
|
||||||
|
optreset = 0;
|
||||||
|
place = nargv[optind];
|
||||||
|
if (optind >= nargc || *place++ != '-') {
|
||||||
|
/* Argument is absent or is not an option */
|
||||||
|
place = EMSG;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
optopt = *place++;
|
||||||
|
if (optopt == '-' && *place == 0) {
|
||||||
|
/* "--" => end of options */
|
||||||
|
++optind;
|
||||||
|
place = EMSG;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (optopt == 0) {
|
||||||
|
/* Solitary '-', treat as a '-' option
|
||||||
|
if the program (eg su) is looking for it. */
|
||||||
|
place = EMSG;
|
||||||
|
if (strchr(ostr, '-') == NULL)
|
||||||
|
return (-1);
|
||||||
|
optopt = '-';
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
optopt = *place++;
|
||||||
|
|
||||||
|
/* See if option letter is one the caller wanted... */
|
||||||
|
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
|
||||||
|
if (*place == 0)
|
||||||
|
++optind;
|
||||||
|
if (opterr && *ostr != ':')
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
#ifndef FSTACK
|
||||||
|
"%s: illegal option -- %c\n", _getprogname(),
|
||||||
|
#else
|
||||||
|
"illegal option -- %c\n",
|
||||||
|
#endif
|
||||||
|
optopt);
|
||||||
|
return (BADCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does this option need an argument? */
|
||||||
|
if (oli[1] != ':') {
|
||||||
|
/* don't need argument */
|
||||||
|
optarg = NULL;
|
||||||
|
if (*place == 0)
|
||||||
|
++optind;
|
||||||
|
} else {
|
||||||
|
/* Option-argument is either the rest of this argument or the
|
||||||
|
entire next argument. */
|
||||||
|
if (*place)
|
||||||
|
optarg = place;
|
||||||
|
else if (oli[2] == ':')
|
||||||
|
/*
|
||||||
|
* GNU Extension, for optional arguments if the rest of
|
||||||
|
* the argument is empty, we return NULL
|
||||||
|
*/
|
||||||
|
optarg = NULL;
|
||||||
|
else if (nargc > ++optind)
|
||||||
|
optarg = nargv[optind];
|
||||||
|
else {
|
||||||
|
/* option-argument absent */
|
||||||
|
place = EMSG;
|
||||||
|
if (*ostr == ':')
|
||||||
|
return (BADARG);
|
||||||
|
if (opterr)
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
#ifndef FSTACK
|
||||||
|
"%s: option requires an argument -- %c\n",
|
||||||
|
_getprogname(), optopt);
|
||||||
|
#else
|
||||||
|
"option requires an argument -- %c\n", optopt);
|
||||||
|
#endif
|
||||||
|
return (BADCH);
|
||||||
|
}
|
||||||
|
place = EMSG;
|
||||||
|
++optind;
|
||||||
|
}
|
||||||
|
return (optopt); /* return option letter */
|
||||||
|
}
|
|
@ -125,6 +125,12 @@ int inet_pton(int, const char * __restrict, void * __restrict);
|
||||||
|
|
||||||
int inet_aton(const char *, struct in_addr *);
|
int inet_aton(const char *, struct in_addr *);
|
||||||
|
|
||||||
|
in_addr_t inet_lnaof(struct in_addr);
|
||||||
|
struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
|
||||||
|
char * inet_neta(in_addr_t, char *, size_t);
|
||||||
|
in_addr_t inet_netof(struct in_addr);
|
||||||
|
in_addr_t inet_network(const char *);
|
||||||
|
|
||||||
#endif /* !_ARPA_INET_H_ */
|
#endif /* !_ARPA_INET_H_ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1986, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)if_arp.h 8.1 (Berkeley) 6/10/93
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NET_IF_ARP_H_
|
||||||
|
#define _NET_IF_ARP_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Address Resolution Protocol.
|
||||||
|
*
|
||||||
|
* See RFC 826 for protocol description. ARP packets are variable
|
||||||
|
* in size; the arphdr structure defines the fixed-length portion.
|
||||||
|
* Protocol type values are the same as those for 10 Mb/s Ethernet.
|
||||||
|
* It is followed by the variable-sized fields ar_sha, arp_spa,
|
||||||
|
* arp_tha and arp_tpa in that order, according to the lengths
|
||||||
|
* specified. Field names used correspond to RFC 826.
|
||||||
|
*/
|
||||||
|
struct arphdr {
|
||||||
|
u_short ar_hrd; /* format of hardware address */
|
||||||
|
#define ARPHRD_ETHER 1 /* ethernet hardware format */
|
||||||
|
#define ARPHRD_IEEE802 6 /* token-ring hardware format */
|
||||||
|
#define ARPHRD_ARCNET 7 /* arcnet hardware format */
|
||||||
|
#define ARPHRD_FRELAY 15 /* frame relay hardware format */
|
||||||
|
#define ARPHRD_IEEE1394 24 /* firewire hardware format */
|
||||||
|
#define ARPHRD_INFINIBAND 32 /* infiniband hardware format */
|
||||||
|
u_short ar_pro; /* format of protocol address */
|
||||||
|
u_char ar_hln; /* length of hardware address */
|
||||||
|
u_char ar_pln; /* length of protocol address */
|
||||||
|
u_short ar_op; /* one of: */
|
||||||
|
#define ARPOP_REQUEST 1 /* request to resolve address */
|
||||||
|
#define ARPOP_REPLY 2 /* response to previous request */
|
||||||
|
#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
|
||||||
|
#define ARPOP_REVREPLY 4 /* response giving protocol address */
|
||||||
|
#define ARPOP_INVREQUEST 8 /* request to identify peer */
|
||||||
|
#define ARPOP_INVREPLY 9 /* response identifying peer */
|
||||||
|
/*
|
||||||
|
* The remaining fields are variable in size,
|
||||||
|
* according to the sizes above.
|
||||||
|
*/
|
||||||
|
#ifdef COMMENT_ONLY
|
||||||
|
u_char ar_sha[]; /* sender hardware address */
|
||||||
|
u_char ar_spa[]; /* sender protocol address */
|
||||||
|
u_char ar_tha[]; /* target hardware address */
|
||||||
|
u_char ar_tpa[]; /* target protocol address */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ar_sha(ap) (((caddr_t)((ap)+1)) + 0)
|
||||||
|
#define ar_spa(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln)
|
||||||
|
#define ar_tha(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln)
|
||||||
|
#define ar_tpa(ap) (((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln)
|
||||||
|
|
||||||
|
#define arphdr_len2(ar_hln, ar_pln) \
|
||||||
|
(sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln))
|
||||||
|
#define arphdr_len(ap) (arphdr_len2((ap)->ar_hln, (ap)->ar_pln))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ARP ioctl request
|
||||||
|
*/
|
||||||
|
struct arpreq {
|
||||||
|
struct sockaddr arp_pa; /* protocol address */
|
||||||
|
struct sockaddr arp_ha; /* hardware address */
|
||||||
|
int arp_flags; /* flags */
|
||||||
|
};
|
||||||
|
/* arp_flags and at_flags field values */
|
||||||
|
#define ATF_INUSE 0x01 /* entry in use */
|
||||||
|
#define ATF_COM 0x02 /* completed entry (enaddr valid) */
|
||||||
|
#define ATF_PERM 0x04 /* permanent entry */
|
||||||
|
#define ATF_PUBL 0x08 /* publish entry (respond for other host) */
|
||||||
|
#define ATF_USETRAILERS 0x10 /* has requested trailers */
|
||||||
|
|
||||||
|
struct arpstat {
|
||||||
|
/* Normal things that happen: */
|
||||||
|
uint64_t txrequests; /* # of ARP requests sent by this host. */
|
||||||
|
uint64_t txreplies; /* # of ARP replies sent by this host. */
|
||||||
|
uint64_t rxrequests; /* # of ARP requests received by this host. */
|
||||||
|
uint64_t rxreplies; /* # of ARP replies received by this host. */
|
||||||
|
uint64_t received; /* # of ARP packets received by this host. */
|
||||||
|
|
||||||
|
uint64_t arp_spares[4]; /* For either the upper or lower half. */
|
||||||
|
/* Abnormal event and error counting: */
|
||||||
|
uint64_t dropped; /* # of packets dropped waiting for a reply. */
|
||||||
|
uint64_t timeouts; /* # of times with entries removed */
|
||||||
|
/* due to timeout. */
|
||||||
|
uint64_t dupips; /* # of duplicate IPs detected. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !_NET_IF_ARP_H_ */
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1982, 1986, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)if_ether.h 8.3 (Berkeley) 5/2/95
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NETINET_IF_ETHER_H_
|
||||||
|
#define _NETINET_IF_ETHER_H_
|
||||||
|
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro to map an IP multicast address to an Ethernet multicast address.
|
||||||
|
* The high-order 25 bits of the Ethernet address are statically assigned,
|
||||||
|
* and the low-order 23 bits are taken from the low end of the IP address.
|
||||||
|
*/
|
||||||
|
#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
|
||||||
|
/* struct in_addr *ipaddr; */ \
|
||||||
|
/* u_char enaddr[ETHER_ADDR_LEN]; */ \
|
||||||
|
{ \
|
||||||
|
(enaddr)[0] = 0x01; \
|
||||||
|
(enaddr)[1] = 0x00; \
|
||||||
|
(enaddr)[2] = 0x5e; \
|
||||||
|
(enaddr)[3] = ((const u_char *)ipaddr)[1] & 0x7f; \
|
||||||
|
(enaddr)[4] = ((const u_char *)ipaddr)[2]; \
|
||||||
|
(enaddr)[5] = ((const u_char *)ipaddr)[3]; \
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Macro to map an IP6 multicast address to an Ethernet multicast address.
|
||||||
|
* The high-order 16 bits of the Ethernet address are statically assigned,
|
||||||
|
* and the low-order 32 bits are taken from the low end of the IP6 address.
|
||||||
|
*/
|
||||||
|
#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \
|
||||||
|
/* struct in6_addr *ip6addr; */ \
|
||||||
|
/* u_char enaddr[ETHER_ADDR_LEN]; */ \
|
||||||
|
{ \
|
||||||
|
(enaddr)[0] = 0x33; \
|
||||||
|
(enaddr)[1] = 0x33; \
|
||||||
|
(enaddr)[2] = ((const u_char *)ip6addr)[12]; \
|
||||||
|
(enaddr)[3] = ((const u_char *)ip6addr)[13]; \
|
||||||
|
(enaddr)[4] = ((const u_char *)ip6addr)[14]; \
|
||||||
|
(enaddr)[5] = ((const u_char *)ip6addr)[15]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ethernet Address Resolution Protocol.
|
||||||
|
*
|
||||||
|
* See RFC 826 for protocol description. Structure below is adapted
|
||||||
|
* to resolving internet addresses. Field names used correspond to
|
||||||
|
* RFC 826.
|
||||||
|
*/
|
||||||
|
struct ether_arp {
|
||||||
|
struct arphdr ea_hdr; /* fixed-size header */
|
||||||
|
u_char arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
|
||||||
|
u_char arp_spa[4]; /* sender protocol address */
|
||||||
|
u_char arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
|
||||||
|
u_char arp_tpa[4]; /* target protocol address */
|
||||||
|
};
|
||||||
|
#define arp_hrd ea_hdr.ar_hrd
|
||||||
|
#define arp_pro ea_hdr.ar_pro
|
||||||
|
#define arp_hln ea_hdr.ar_hln
|
||||||
|
#define arp_pln ea_hdr.ar_pln
|
||||||
|
#define arp_op ea_hdr.ar_op
|
||||||
|
|
||||||
|
#ifndef BURN_BRIDGES /* Can be used by third party software. */
|
||||||
|
struct sockaddr_inarp {
|
||||||
|
u_char sin_len;
|
||||||
|
u_char sin_family;
|
||||||
|
u_short sin_port;
|
||||||
|
struct in_addr sin_addr;
|
||||||
|
struct in_addr sin_srcaddr;
|
||||||
|
u_short sin_tos;
|
||||||
|
u_short sin_other;
|
||||||
|
#define SIN_PROXY 1
|
||||||
|
};
|
||||||
|
#endif /* !BURN_BRIDGES */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IP and ethernet specific routing flags
|
||||||
|
*/
|
||||||
|
#define RTF_USETRAILERS RTF_PROTO1 /* use trailers */
|
||||||
|
#define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,10 +49,6 @@ int fake_close(int fd);
|
||||||
#define socket(a, b, c) fake_socket((a), (b), (c))
|
#define socket(a, b, c) fake_socket((a), (b), (c))
|
||||||
#define close(a) fake_close((a))
|
#define close(a) fake_close((a))
|
||||||
|
|
||||||
#ifndef nitems
|
|
||||||
#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct afswtch;
|
struct afswtch;
|
||||||
|
|
|
@ -35,7 +35,9 @@ SRCS= ${PROG}.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJS+= $(patsubst %.cc,%.o,$(patsubst %.c,%.o,${SRCS}))
|
HEADERS+= $(filter %.h,${SRCS})
|
||||||
|
OBJS+= $(patsubst %.c,%.o, $(filter %.c,${SRCS}))
|
||||||
|
OBJS+= $(patsubst %.cc,%.o, $(filter %.cc,${SRCS}))
|
||||||
|
|
||||||
ifeq ($(FF_DPDK),)
|
ifeq ($(FF_DPDK),)
|
||||||
FF_DPDK=${TOPDIR}/dpdk/x86_64-native-linuxapp-gcc
|
FF_DPDK=${TOPDIR}/dpdk/x86_64-native-linuxapp-gcc
|
||||||
|
@ -57,7 +59,9 @@ CXXFLAGS+= ${FF_PROG_CFLAGS}
|
||||||
|
|
||||||
LIBS+= ${FF_PROG_LIBS}
|
LIBS+= ${FF_PROG_LIBS}
|
||||||
|
|
||||||
${PROG}: ${OBJS}
|
CLEANFILES+= ${PROG} ${OBJS}
|
||||||
|
|
||||||
|
${PROG}: ${HEADERS} ${OBJS}
|
||||||
ifdef PROG_CXX
|
ifdef PROG_CXX
|
||||||
${CXX} ${CXXFLAGS} ${LDFLAGS} -o $@ ${OBJS} ${LIBS}
|
${CXX} ${CXXFLAGS} ${LDFLAGS} -o $@ ${OBJS} ${LIBS}
|
||||||
else
|
else
|
||||||
|
@ -65,6 +69,6 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f ${PROG} ${OBJS}
|
@rm -f ${CLEANFILES}
|
||||||
|
|
||||||
all: ${PROG}
|
all: ${PROG}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
TOPDIR?=${CURDIR}/../..
|
||||||
|
include ${TOPDIR}/tools/opts.mk
|
||||||
|
|
||||||
|
PROG= route
|
||||||
|
MAN= route.8
|
||||||
|
SRCS= route.c keywords.h
|
||||||
|
WARNS?= 3
|
||||||
|
CLEANFILES+=keywords.h
|
||||||
|
|
||||||
|
CFLAGS+= -DNS
|
||||||
|
ifneq (${MK_INET_SUPPORT},"no")
|
||||||
|
CFLAGS+= -DINET
|
||||||
|
endif
|
||||||
|
ifneq (${MK_INET6_SUPPORT},"no")
|
||||||
|
CFLAGS+= -DINET6
|
||||||
|
endif
|
||||||
|
CFLAGS+= -I.
|
||||||
|
|
||||||
|
include ${TOPDIR}/tools/prog.mk
|
||||||
|
|
||||||
|
keywords.h: keywords
|
||||||
|
LC_ALL=C awk '!/^#|^$$/ { \
|
||||||
|
printf "#define\tK_%s\t%d\n\t{\"%s\", K_%s},\n", \
|
||||||
|
toupper($$1), ++L, $$1, toupper($$1); \
|
||||||
|
}' < ${CURDIR}/keywords > $@
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
# @(#)keywords 8.2 (Berkeley) 3/19/94
|
||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
4
|
||||||
|
6
|
||||||
|
add
|
||||||
|
blackhole
|
||||||
|
change
|
||||||
|
cloning
|
||||||
|
del
|
||||||
|
delete
|
||||||
|
dst
|
||||||
|
expire
|
||||||
|
fib
|
||||||
|
flush
|
||||||
|
gateway
|
||||||
|
genmask
|
||||||
|
get
|
||||||
|
host
|
||||||
|
hopcount
|
||||||
|
iface
|
||||||
|
interface
|
||||||
|
ifa
|
||||||
|
ifp
|
||||||
|
inet
|
||||||
|
inet6
|
||||||
|
iso
|
||||||
|
link
|
||||||
|
llinfo
|
||||||
|
lock
|
||||||
|
lockrest
|
||||||
|
mask
|
||||||
|
monitor
|
||||||
|
mtu
|
||||||
|
net
|
||||||
|
netmask
|
||||||
|
nostatic
|
||||||
|
nostick
|
||||||
|
osi
|
||||||
|
prefixlen
|
||||||
|
proto1
|
||||||
|
proto2
|
||||||
|
proxy
|
||||||
|
recvpipe
|
||||||
|
reject
|
||||||
|
rtt
|
||||||
|
rttvar
|
||||||
|
sa
|
||||||
|
sendpipe
|
||||||
|
show
|
||||||
|
ssthresh
|
||||||
|
static
|
||||||
|
sticky
|
||||||
|
weight
|
||||||
|
x25
|
||||||
|
xns
|
||||||
|
xresolve
|
|
@ -0,0 +1,506 @@
|
||||||
|
.\" Copyright (c) 1983, 1991, 1993
|
||||||
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 4. Neither the name of the University nor the names of its contributors
|
||||||
|
.\" may be used to endorse or promote products derived from this software
|
||||||
|
.\" without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" @(#)route.8 8.3 (Berkeley) 3/19/94
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.\"
|
||||||
|
.Dd November 11, 2014
|
||||||
|
.Dt ROUTE 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm route
|
||||||
|
.Nd manually manipulate the routing tables
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl dnqtv
|
||||||
|
.Ar command
|
||||||
|
.Oo
|
||||||
|
.Op Ar modifiers
|
||||||
|
.Ar args
|
||||||
|
.Oc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is used to manually manipulate the network
|
||||||
|
routing tables.
|
||||||
|
It normally is not needed, as a
|
||||||
|
system routing table management daemon, such as
|
||||||
|
.Xr routed 8 ,
|
||||||
|
should tend to this task.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility supports a limited number of general options,
|
||||||
|
but a rich command language, enabling the user to specify
|
||||||
|
any arbitrary request that could be delivered via the
|
||||||
|
programmatic interface discussed in
|
||||||
|
.Xr route 4 .
|
||||||
|
.Pp
|
||||||
|
The following options are available:
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Fl 4
|
||||||
|
Specify
|
||||||
|
.Cm inet
|
||||||
|
address family as family hint for subcommands.
|
||||||
|
.It Fl 6
|
||||||
|
Specify
|
||||||
|
.Cm inet
|
||||||
|
address family as family hint for subcommands.
|
||||||
|
.It Fl d
|
||||||
|
Run in debug-only mode, i.e., do not actually modify the routing table.
|
||||||
|
.It Fl n
|
||||||
|
Bypass attempts to print host and network names symbolically
|
||||||
|
when reporting actions.
|
||||||
|
(The process of translating between symbolic
|
||||||
|
names and numerical equivalents can be quite time consuming, and
|
||||||
|
may require correct operation of the network; thus it may be expedient
|
||||||
|
to forget this, especially when attempting to repair networking operations).
|
||||||
|
.It Fl t
|
||||||
|
Run in test-only mode.
|
||||||
|
.Pa /dev/null
|
||||||
|
is used instead of a socket.
|
||||||
|
.It Fl v
|
||||||
|
(verbose) Print additional details.
|
||||||
|
.It Fl q
|
||||||
|
Suppress all output from the
|
||||||
|
.Cm add , change , delete ,
|
||||||
|
and
|
||||||
|
.Cm flush
|
||||||
|
commands.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility provides the following commands:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width Fl -compact
|
||||||
|
.It Cm add
|
||||||
|
Add a route.
|
||||||
|
.It Cm flush
|
||||||
|
Remove all routes.
|
||||||
|
.It Cm delete
|
||||||
|
Delete a specific route.
|
||||||
|
.It Cm del
|
||||||
|
Another name for the
|
||||||
|
.Cm delete
|
||||||
|
command.
|
||||||
|
.It Cm change
|
||||||
|
Change aspects of a route (such as its gateway).
|
||||||
|
.It Cm get
|
||||||
|
Lookup and display the route for a destination.
|
||||||
|
.It Cm monitor
|
||||||
|
Continuously report any changes to the routing information base,
|
||||||
|
routing lookup misses, or suspected network partitionings.
|
||||||
|
.It Cm show
|
||||||
|
Another name for the
|
||||||
|
.Cm get
|
||||||
|
command.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The monitor command has the syntax:
|
||||||
|
.Pp
|
||||||
|
.Bd -ragged -offset indent -compact
|
||||||
|
.Nm
|
||||||
|
.Op Fl n
|
||||||
|
.Cm monitor Op Fl fib Ar number
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The flush command has the syntax:
|
||||||
|
.Pp
|
||||||
|
.Bd -ragged -offset indent -compact
|
||||||
|
.Nm
|
||||||
|
.Oo Fl n Cm flush Oc Oo Ar family Oc Op Fl fib Ar number
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
If the
|
||||||
|
.Cm flush
|
||||||
|
command is specified,
|
||||||
|
.Nm
|
||||||
|
will ``flush'' the routing tables of all gateway entries.
|
||||||
|
When the address family may is specified by any of the
|
||||||
|
.Fl osi ,
|
||||||
|
.Fl xns ,
|
||||||
|
.Fl inet6 ,
|
||||||
|
or
|
||||||
|
.Fl inet
|
||||||
|
modifiers, only routes having destinations with addresses in the
|
||||||
|
delineated family will be deleted.
|
||||||
|
Additionally,
|
||||||
|
.Fl 4
|
||||||
|
or
|
||||||
|
.Fl 6
|
||||||
|
can be used as aliases for
|
||||||
|
.Fl inet
|
||||||
|
and
|
||||||
|
.Fl inet6
|
||||||
|
modifiers.
|
||||||
|
When a
|
||||||
|
.Fl fib
|
||||||
|
option is specified, the operation will be applied to
|
||||||
|
the specified FIB
|
||||||
|
.Pq routing table .
|
||||||
|
.Pp
|
||||||
|
The other commands have the following syntax:
|
||||||
|
.Pp
|
||||||
|
.Bd -ragged -offset indent -compact
|
||||||
|
.Nm
|
||||||
|
.Op Fl n
|
||||||
|
.Ar command
|
||||||
|
.Op Fl net No \&| Fl host
|
||||||
|
.Ar destination gateway
|
||||||
|
.Op Ar netmask
|
||||||
|
.Op Fl fib Ar number
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
where
|
||||||
|
.Ar destination
|
||||||
|
is the destination host or network,
|
||||||
|
.Ar gateway
|
||||||
|
is the next-hop intermediary via which packets should be routed.
|
||||||
|
Routes to a particular host may be distinguished from those to
|
||||||
|
a network by interpreting the Internet address specified as the
|
||||||
|
.Ar destination
|
||||||
|
argument.
|
||||||
|
The optional modifiers
|
||||||
|
.Fl net
|
||||||
|
and
|
||||||
|
.Fl host
|
||||||
|
force the destination to be interpreted as a network or a host, respectively.
|
||||||
|
Otherwise, if the
|
||||||
|
.Ar destination
|
||||||
|
has a
|
||||||
|
.Dq local address part
|
||||||
|
of
|
||||||
|
INADDR_ANY
|
||||||
|
.Pq Li 0.0.0.0 ,
|
||||||
|
or if the
|
||||||
|
.Ar destination
|
||||||
|
is the symbolic name of a network, then the route is
|
||||||
|
assumed to be to a network; otherwise, it is presumed to be a
|
||||||
|
route to a host.
|
||||||
|
Optionally, the
|
||||||
|
.Ar destination
|
||||||
|
could also be specified in the
|
||||||
|
.Ar net Ns / Ns Ar bits
|
||||||
|
format.
|
||||||
|
.Pp
|
||||||
|
For example,
|
||||||
|
.Li 128.32
|
||||||
|
is interpreted as
|
||||||
|
.Fl host Li 128.0.0.32 ;
|
||||||
|
.Li 128.32.130
|
||||||
|
is interpreted as
|
||||||
|
.Fl host Li 128.32.0.130 ;
|
||||||
|
.Fl net Li 128.32
|
||||||
|
is interpreted as
|
||||||
|
.Li 128.32.0.0;
|
||||||
|
.Fl net Li 128.32.130
|
||||||
|
is interpreted as
|
||||||
|
.Li 128.32.130.0;
|
||||||
|
and
|
||||||
|
.Li 192.168.64/20
|
||||||
|
is interpreted as
|
||||||
|
.Fl net Li 192.168.64 Fl netmask Li 255.255.240.0 .
|
||||||
|
.Pp
|
||||||
|
A
|
||||||
|
.Ar destination
|
||||||
|
of
|
||||||
|
.Ar default
|
||||||
|
is a synonym for the default route.
|
||||||
|
For
|
||||||
|
.Li IPv4
|
||||||
|
it is
|
||||||
|
.Fl net Fl inet Li 0.0.0.0 ,
|
||||||
|
and for
|
||||||
|
.Li IPv6
|
||||||
|
it is
|
||||||
|
.Fl net Fl inet6 Li :: .
|
||||||
|
.Pp
|
||||||
|
If the destination is directly reachable
|
||||||
|
via an interface requiring
|
||||||
|
no intermediary system to act as a gateway, the
|
||||||
|
.Fl interface
|
||||||
|
modifier should be specified;
|
||||||
|
the gateway given is the address of this host on the common network,
|
||||||
|
indicating the interface to be used for transmission.
|
||||||
|
Alternately, if the interface is point to point the name of the interface
|
||||||
|
itself may be given, in which case the route remains valid even
|
||||||
|
if the local or remote addresses change.
|
||||||
|
.Pp
|
||||||
|
The optional modifiers
|
||||||
|
.Fl xns ,
|
||||||
|
.Fl osi ,
|
||||||
|
and
|
||||||
|
.Fl link
|
||||||
|
specify that all subsequent addresses are in the
|
||||||
|
.Tn XNS
|
||||||
|
or
|
||||||
|
.Tn OSI
|
||||||
|
address families,
|
||||||
|
or are specified as link-level addresses,
|
||||||
|
and the names must be numeric specifications rather than
|
||||||
|
symbolic names.
|
||||||
|
.Pp
|
||||||
|
The optional
|
||||||
|
.Fl netmask
|
||||||
|
modifier is intended
|
||||||
|
to achieve the effect of an
|
||||||
|
.Tn OSI
|
||||||
|
.Tn ESIS
|
||||||
|
redirect with the netmask option,
|
||||||
|
or to manually add subnet routes with
|
||||||
|
netmasks different from that of the implied network interface
|
||||||
|
(as would otherwise be communicated using the OSPF or ISIS routing protocols).
|
||||||
|
One specifies an additional ensuing address parameter
|
||||||
|
(to be interpreted as a network mask).
|
||||||
|
The implicit network mask generated in the AF_INET case
|
||||||
|
can be overridden by making sure this option follows the destination parameter.
|
||||||
|
.Pp
|
||||||
|
For
|
||||||
|
.Dv AF_INET6 ,
|
||||||
|
the
|
||||||
|
.Fl prefixlen
|
||||||
|
qualifier
|
||||||
|
is available instead of the
|
||||||
|
.Fl mask
|
||||||
|
qualifier because non-continuous masks are not allowed in IPv6.
|
||||||
|
For example,
|
||||||
|
.Fl prefixlen Li 32
|
||||||
|
specifies network mask of
|
||||||
|
.Li ffff:ffff:0000:0000:0000:0000:0000:0000
|
||||||
|
to be used.
|
||||||
|
The default value of prefixlen is 64 to get along with
|
||||||
|
the aggregatable address.
|
||||||
|
But 0 is assumed if
|
||||||
|
.Cm default
|
||||||
|
is specified.
|
||||||
|
Note that the qualifier works only for
|
||||||
|
.Dv AF_INET6
|
||||||
|
address family.
|
||||||
|
.Pp
|
||||||
|
Routes have associated flags which influence operation of the protocols
|
||||||
|
when sending to destinations matched by the routes.
|
||||||
|
These flags may be set (or sometimes cleared)
|
||||||
|
by indicating the following corresponding modifiers:
|
||||||
|
.Bd -literal
|
||||||
|
-xresolve RTF_XRESOLVE - emit mesg on use (for external lookup)
|
||||||
|
-iface ~RTF_GATEWAY - destination is directly reachable
|
||||||
|
-static RTF_STATIC - manually added route
|
||||||
|
-nostatic ~RTF_STATIC - pretend route added by kernel or daemon
|
||||||
|
-reject RTF_REJECT - emit an ICMP unreachable when matched
|
||||||
|
-blackhole RTF_BLACKHOLE - silently discard pkts (during updates)
|
||||||
|
-proto1 RTF_PROTO1 - set protocol specific routing flag #1
|
||||||
|
-proto2 RTF_PROTO2 - set protocol specific routing flag #2
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The optional modifiers
|
||||||
|
.Fl rtt ,
|
||||||
|
.Fl rttvar ,
|
||||||
|
.Fl sendpipe ,
|
||||||
|
.Fl recvpipe ,
|
||||||
|
.Fl mtu ,
|
||||||
|
.Fl hopcount ,
|
||||||
|
.Fl expire ,
|
||||||
|
and
|
||||||
|
.Fl ssthresh
|
||||||
|
provide initial values to quantities maintained in the routing entry
|
||||||
|
by transport level protocols, such as TCP or TP4.
|
||||||
|
These may be individually locked by preceding each such modifier to
|
||||||
|
be locked by
|
||||||
|
the
|
||||||
|
.Fl lock
|
||||||
|
meta-modifier, or one can
|
||||||
|
specify that all ensuing metrics may be locked by the
|
||||||
|
.Fl lockrest
|
||||||
|
meta-modifier.
|
||||||
|
.Pp
|
||||||
|
Note that
|
||||||
|
.Fl expire
|
||||||
|
accepts expiration time of the route as the number of seconds since the
|
||||||
|
Epoch
|
||||||
|
.Pq see Xr time 3 .
|
||||||
|
When the first character of the number is
|
||||||
|
.Dq +
|
||||||
|
or
|
||||||
|
.Dq - ,
|
||||||
|
it is interpreted as a value relative to the current time.
|
||||||
|
.Pp
|
||||||
|
The optional modifier
|
||||||
|
.Fl fib Ar number
|
||||||
|
specifies that the command will be applied to a non-default FIB.
|
||||||
|
The
|
||||||
|
.Ar number
|
||||||
|
must be smaller than the
|
||||||
|
.Va net.fibs
|
||||||
|
.Xr sysctl 8
|
||||||
|
MIB.
|
||||||
|
When this modifier is not specified,
|
||||||
|
or a negative number is specified,
|
||||||
|
the default FIB shown in the
|
||||||
|
.Va net.my_fibnum
|
||||||
|
.Xr sysctl 8
|
||||||
|
MIB will be used.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar number
|
||||||
|
allows multiple FIBs by a comma-separeted list and/or range
|
||||||
|
specification.
|
||||||
|
The
|
||||||
|
.Qq Fl fib Li 2,4,6
|
||||||
|
means the FIB number 2, 4, and 6.
|
||||||
|
The
|
||||||
|
.Qq Fl fib Li 1,3-5,6
|
||||||
|
means the 1, 3, 4, 5, and 6.
|
||||||
|
.Pp
|
||||||
|
In a
|
||||||
|
.Cm change
|
||||||
|
or
|
||||||
|
.Cm add
|
||||||
|
command where the destination and gateway are not sufficient to specify
|
||||||
|
the route (as in the
|
||||||
|
.Tn ISO
|
||||||
|
case where several interfaces may have the
|
||||||
|
same address), the
|
||||||
|
.Fl ifp
|
||||||
|
or
|
||||||
|
.Fl ifa
|
||||||
|
modifiers may be used to determine the interface or interface address.
|
||||||
|
.Pp
|
||||||
|
All symbolic names specified for a
|
||||||
|
.Ar destination
|
||||||
|
or
|
||||||
|
.Ar gateway
|
||||||
|
are looked up first as a host name using
|
||||||
|
.Xr gethostbyname 3 .
|
||||||
|
If this lookup fails,
|
||||||
|
.Xr getnetbyname 3
|
||||||
|
is then used to interpret the name as that of a network.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility uses a routing socket and the new message types
|
||||||
|
.Dv RTM_ADD , RTM_DELETE , RTM_GET ,
|
||||||
|
and
|
||||||
|
.Dv RTM_CHANGE .
|
||||||
|
As such, only the super-user may modify
|
||||||
|
the routing tables.
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
.Ex -std
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Add a default route to the network routing table.
|
||||||
|
This will send all packets for destinations not available in the routing table
|
||||||
|
to the default gateway at 192.168.1.1:
|
||||||
|
.Pp
|
||||||
|
.Dl route add -net 0.0.0.0/0 192.168.1.1
|
||||||
|
.Pp
|
||||||
|
A shorter version of adding a default route can also be written as:
|
||||||
|
.Pp
|
||||||
|
.Dl route add default 192.168.1.1
|
||||||
|
.Pp
|
||||||
|
Add a static route to the 172.16.10.0/24 network via the 172.16.1.1 gateway:
|
||||||
|
.Pp
|
||||||
|
.Dl route add -net 172.16.10.0/24 172.16.1.1
|
||||||
|
.Pp
|
||||||
|
Change the gateway of an already established static route in the routing table:
|
||||||
|
.Pp
|
||||||
|
.Dl route change -net 172.16.10.0/24 172.16.1.2
|
||||||
|
.Pp
|
||||||
|
Display the route for a destination network:
|
||||||
|
.Pp
|
||||||
|
.Dl route show 172.16.10.0
|
||||||
|
.Pp
|
||||||
|
Delete a static route from the routing table:
|
||||||
|
.Pp
|
||||||
|
.Dl route delete -net 172.16.10.0/24 172.16.1.2
|
||||||
|
.Pp
|
||||||
|
Remove all routes from the routing table:
|
||||||
|
.Pp
|
||||||
|
.Dl route flush
|
||||||
|
.Sh DIAGNOSTICS
|
||||||
|
.Bl -diag
|
||||||
|
.It "add [host \&| network ] %s: gateway %s flags %x"
|
||||||
|
The specified route is being added to the tables.
|
||||||
|
The
|
||||||
|
values printed are from the routing table entry supplied
|
||||||
|
in the
|
||||||
|
.Xr ioctl 2
|
||||||
|
call.
|
||||||
|
If the gateway address used was not the primary address of the gateway
|
||||||
|
(the first one returned by
|
||||||
|
.Xr gethostbyname 3 ) ,
|
||||||
|
the gateway address is printed numerically as well as symbolically.
|
||||||
|
.It "delete [ host \&| network ] %s: gateway %s flags %x"
|
||||||
|
As above, but when deleting an entry.
|
||||||
|
.It "%s %s done"
|
||||||
|
When the
|
||||||
|
.Cm flush
|
||||||
|
command is specified, each routing table entry deleted
|
||||||
|
is indicated with a message of this form.
|
||||||
|
.It "Network is unreachable"
|
||||||
|
An attempt to add a route failed because the gateway listed was not
|
||||||
|
on a directly-connected network.
|
||||||
|
The next-hop gateway must be given.
|
||||||
|
.It "not in table"
|
||||||
|
A delete operation was attempted for an entry which
|
||||||
|
was not present in the tables.
|
||||||
|
.It "routing table overflow"
|
||||||
|
An add operation was attempted, but the system was
|
||||||
|
low on resources and was unable to allocate memory
|
||||||
|
to create the new entry.
|
||||||
|
.It "gateway uses the same route"
|
||||||
|
A
|
||||||
|
.Cm change
|
||||||
|
operation resulted in a route whose gateway uses the
|
||||||
|
same route as the one being changed.
|
||||||
|
The next-hop gateway should be reachable through a different route.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.\".Xr esis 4 ,
|
||||||
|
.Xr netintro 4 ,
|
||||||
|
.Xr route 4 ,
|
||||||
|
.Xr arp 8 ,
|
||||||
|
.Xr routed 8
|
||||||
|
.\".Xr XNSrouted 8
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility appeared in
|
||||||
|
.Bx 4.2 .
|
||||||
|
.Sh BUGS
|
||||||
|
The first paragraph may have slightly exaggerated
|
||||||
|
.Xr routed 8 Ns 's
|
||||||
|
abilities.
|
||||||
|
.Pp
|
||||||
|
Currently, routes with the
|
||||||
|
.Dv RTF_BLACKHOLE
|
||||||
|
flag set need to have the gateway set to an instance of the
|
||||||
|
.Xr lo 4
|
||||||
|
driver, using the
|
||||||
|
.Fl iface
|
||||||
|
option, for the flag to have any effect; unless IP fast forwarding
|
||||||
|
is enabled, in which case the meaning of the flag will always
|
||||||
|
be honored.
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue