summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ifconfig/Makefile1
-rw-r--r--sbin/ifconfig/ifconfig.815
-rw-r--r--sbin/ifconfig/iffib.c103
-rw-r--r--share/man/man9/ifnet.911
-rw-r--r--sys/kern/kern_jail.c1
-rw-r--r--sys/net/if.c16
-rw-r--r--sys/net/if.h2
-rw-r--r--sys/net/if_debug.c1
-rw-r--r--sys/net/if_var.h1
-rw-r--r--sys/sys/priv.h1
-rw-r--r--sys/sys/sockio.h3
11 files changed, 152 insertions, 3 deletions
diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile
index 461de71..d4bdd1e 100644
--- a/sbin/ifconfig/Makefile
+++ b/sbin/ifconfig/Makefile
@@ -29,6 +29,7 @@ SRCS+= af_nd6.c # ND6 support
SRCS+= ifclone.c # clone device support
SRCS+= ifmac.c # MAC support
SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support
+SRCS+= iffib.c # non-default FIB support
SRCS+= ifvlan.c # SIOC[GS]ETVLAN support
SRCS+= ifgre.c # GRE keys etc
SRCS+= ifgif.c # GIF reversed header workaround
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 45cf59b..cec32c5 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
-.Dd May 31, 2011
+.Dd July 3, 2011
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -296,6 +296,19 @@ Remove the interface from the given
Fill interface index
(lowermost 64bit of an IPv6 address)
automatically.
+.It Cm fib Ar fib_number
+Specify interface FIB.
+A FIB
+.Ar fib_number
+is assigned to all frames or packets received on that interface.
+The FIB is not inherited, e.g. vlans or other sub-interfaces will use
+the default FIB (0) irrespective of the parent interface's FIB.
+The kernel needs to be tuned to support more than the default FIB
+using the
+.Va ROUTETABLES
+kernel configuration option, or the
+.Va net.fibs
+tunable.
.It Cm ipdst
This is used to specify an Internet host who is willing to receive
IP packets encapsulating IPX packets bound for a remote network.
diff --git a/sbin/ifconfig/iffib.c b/sbin/ifconfig/iffib.c
new file mode 100644
index 0000000..f3498b4
--- /dev/null
+++ b/sbin/ifconfig/iffib.c
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 2011 Alexander V. Chernikov
+ * Copyright (c) 2011 Christian S.J. Peron
+ * Copyright (c) 2011 Bjoern A. Zeeb
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+
+#include "ifconfig.h"
+
+static void
+fib_status(int s)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ if (ioctl(s, SIOCGIFFIB, (caddr_t)&ifr) < 0)
+ return;
+
+ /* Ignore if it is the default. */
+ if (ifr.ifr_fib == 0)
+ return;
+
+ printf("\tfib: %u\n", ifr.ifr_fib);
+}
+
+static void
+setiffib(const char *val, int dummy __unused, int s,
+ const struct afswtch *afp)
+{
+ unsigned long fib;
+ char *ep;
+
+ fib = strtoul(val, &ep, 0);
+ if (*ep != '\0' || fib > UINT_MAX) {
+ warn("fib %s not valid", val);
+ return;
+ }
+
+ strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ ifr.ifr_fib = fib;
+ if (ioctl(s, SIOCSIFFIB, (caddr_t)&ifr) < 0)
+ warn("ioctl (SIOCSIFFIB)");
+}
+
+static struct cmd fib_cmds[] = {
+ DEF_CMD_ARG("fib", setiffib),
+};
+
+static struct afswtch af_fib = {
+ .af_name = "af_fib",
+ .af_af = AF_UNSPEC,
+ .af_other_status = fib_status,
+};
+
+static __constructor void
+fib_ctor(void)
+{
+#define N(a) (sizeof(a) / sizeof(a[0]))
+ size_t i;
+
+ for (i = 0; i < N(fib_cmds); i++)
+ cmd_register(&fib_cmds[i]);
+ af_register(&af_fib);
+#undef N
+}
diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9
index e9dbab5..05264dc 100644
--- a/share/man/man9/ifnet.9
+++ b/share/man/man9/ifnet.9
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 1, 2009
+.Dd July 3, 2011
.Dt IFNET 9
.Os
.Sh NAME
@@ -1169,11 +1169,12 @@ list.
Caller must have appropriate privilege.
(No call-down to driver.)
.It Dv SIOCGIFCAP
+.It Dv SIOCGIFFIB
.It Dv SIOCGIFFLAGS
.It Dv SIOCGIFMETRIC
.It Dv SIOCGIFMTU
.It Dv SIOCGIFPHYS
-Get interface capabilities, flags, metric, MTU, medium selection.
+Get interface capabilities, FIB, flags, metric, MTU, medium selection.
(No call-down to driver.)
.Pp
.It Dv SIOCSIFCAP
@@ -1192,6 +1193,12 @@ and
.Va if_data.ifi_hwassist
appropriately.
.Pp
+.It Dv SIOCSIFFIB
+Sets interface FIB.
+Caller must have appropriate privilege.
+FIB values start at 0 and values greater or equals than
+.Va net.fibs
+are considered invalid.
.It Dv SIOCSIFFLAGS
Change interface flags.
Caller must have appropriate privilege.
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 5850ad1..358d673 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3639,6 +3639,7 @@ prison_priv_check(struct ucred *cred, int priv)
case PRIV_NET_LAGG:
case PRIV_NET_GIF:
case PRIV_NET_SETIFVNET:
+ case PRIV_NET_SETIFFIB:
/*
* 802.11-related privileges.
diff --git a/sys/net/if.c b/sys/net/if.c
index a5a3a8e..2b7a24a 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -58,6 +58,8 @@
#include <sys/taskqueue.h>
#include <sys/domain.h>
#include <sys/jail.h>
+#include <sys/priv.h>
+
#include <machine/stdarg.h>
#include <vm/uma.h>
@@ -2135,6 +2137,20 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
free(odescrbuf, M_IFDESCR);
break;
+ case SIOCGIFFIB:
+ ifr->ifr_fib = ifp->if_fib;
+ break;
+
+ case SIOCSIFFIB:
+ error = priv_check(td, PRIV_NET_SETIFFIB);
+ if (error)
+ return (error);
+ if (ifr->ifr_fib >= rt_numfibs)
+ return (EINVAL);
+
+ ifp->if_fib = ifr->ifr_fib;
+ break;
+
case SIOCSIFFLAGS:
error = priv_check(td, PRIV_NET_SETIFFLAGS);
if (error)
diff --git a/sys/net/if.h b/sys/net/if.h
index 06521cb..d1f3883 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -325,6 +325,7 @@ struct ifreq {
int ifru_media;
caddr_t ifru_data;
int ifru_cap[2];
+ u_int ifru_fib;
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
@@ -341,6 +342,7 @@ struct ifreq {
#define ifr_reqcap ifr_ifru.ifru_cap[0] /* requested capabilities */
#define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */
#define ifr_index ifr_ifru.ifru_index /* interface index */
+#define ifr_fib ifr_ifru.ifru_fib /* interface fib */
};
#define _SIZEOF_ADDR_IFREQ(ifr) \
diff --git a/sys/net/if_debug.c b/sys/net/if_debug.c
index dcf504e..e7319374 100644
--- a/sys/net/if_debug.c
+++ b/sys/net/if_debug.c
@@ -86,6 +86,7 @@ if_show_ifnet(struct ifnet *ifp)
IF_DB_PRINTF("%d", if_snd.ifq_drv_maxlen);
IF_DB_PRINTF("%d", if_snd.altq_type);
IF_DB_PRINTF("%x", if_snd.altq_flags);
+ IF_DB_PRINTF("%u", if_fib);
#undef IF_DB_PRINTF
}
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index b3ecb7d..cb1d39c 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -196,6 +196,7 @@ struct ifnet {
void *if_pf_kif;
void *if_lagg; /* lagg glue */
u_char if_alloctype; /* if_type at time of allocation */
+ u_int if_fib; /* interface FIB */
/*
* Spare fields are added so that we can modify sensitive data
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
index 7733e36..b984f1a 100644
--- a/sys/sys/priv.h
+++ b/sys/sys/priv.h
@@ -337,6 +337,7 @@
#define PRIV_NET_GIF 416 /* Administer gif interface. */
#define PRIV_NET_SETIFVNET 417 /* Move interface to vnet. */
#define PRIV_NET_SETIFDESCR 418 /* Set interface description. */
+#define PRIV_NET_SETIFFIB 419 /* Set interface fib. */
/*
* 802.11-related privileges.
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 4c1c483..8922699 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -110,6 +110,9 @@
#define SIOCSIFVNET _IOWR('i', 90, struct ifreq) /* move IF jail/vnet */
#define SIOCSIFRVNET _IOWR('i', 91, struct ifreq) /* reclaim vnet IF */
+#define SIOCGIFFIB _IOWR('i', 92, struct ifreq) /* get IF fib */
+#define SIOCSIFFIB _IOW('i', 93, struct ifreq) /* set IF fib */
+
#define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific
parameters */
#define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific
OpenPOWER on IntegriCloud