aboutsummaryrefslogtreecommitdiff
path: root/sbin/ifconfig/ifclone.c
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2020-10-21 21:28:20 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2020-10-21 21:28:20 +0000
commitc7cffd65c5d858425e90b847d2e8e583e3b13bf7 (patch)
tree43a36ae6b443b446902f50162ee514f2429996e8 /sbin/ifconfig/ifclone.c
parent37d411338e9de344d53ea7d55c4f886978bd8171 (diff)
Add support for stacked VLANs (IEEE 802.1ad, AKA Q-in-Q).
802.1ad interfaces are created with ifconfig using the "vlanproto" parameter. Eg., the following creates a 802.1Q VLAN (id #42) over a 802.1ad S-VLAN (id #5) over a physical Ethernet interface (em0). ifconfig vlan5 create vlandev em0 vlan 5 vlanproto 802.1ad up ifconfig vlan42 create vlandev vlan5 vlan 42 inet 10.5.42.1/24 VLAN_MTU, VLAN_HWCSUM and VLAN_TSO capabilities should be properly supported. VLAN_HWTAGGING is only partially supported, as there is currently no IFCAP_VLAN_* denoting the possibility to set the VLAN EtherType to anything else than 0x8100 (802.1ad uses 0x88A8). Submitted by: Olivier Piras Sponsored by: RG Nets Differential Revision: https://reviews.freebsd.org/D26436
Notes
Notes: svn path=/head/; revision=366917
Diffstat (limited to 'sbin/ifconfig/ifclone.c')
-rw-r--r--sbin/ifconfig/ifclone.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/sbin/ifconfig/ifclone.c b/sbin/ifconfig/ifclone.c
index 134bb0af3efa..58bc3b3103ee 100644
--- a/sbin/ifconfig/ifclone.c
+++ b/sbin/ifconfig/ifclone.c
@@ -49,6 +49,11 @@ static const char rcsid[] =
#include "ifconfig.h"
+typedef enum {
+ MT_PREFIX,
+ MT_FILTER,
+} clone_match_type;
+
static void
list_cloners(void)
{
@@ -76,7 +81,11 @@ list_cloners(void)
}
struct clone_defcb {
- char ifprefix[IFNAMSIZ];
+ union {
+ char ifprefix[IFNAMSIZ];
+ clone_match_func *ifmatch;
+ };
+ clone_match_type clone_mt;
clone_callback_func *clone_cb;
SLIST_ENTRY(clone_defcb) next;
};
@@ -85,12 +94,25 @@ static SLIST_HEAD(, clone_defcb) clone_defcbh =
SLIST_HEAD_INITIALIZER(clone_defcbh);
void
-clone_setdefcallback(const char *ifprefix, clone_callback_func *p)
+clone_setdefcallback_prefix(const char *ifprefix, clone_callback_func *p)
{
struct clone_defcb *dcp;
dcp = malloc(sizeof(*dcp));
strlcpy(dcp->ifprefix, ifprefix, IFNAMSIZ-1);
+ dcp->clone_mt = MT_PREFIX;
+ dcp->clone_cb = p;
+ SLIST_INSERT_HEAD(&clone_defcbh, dcp, next);
+}
+
+void
+clone_setdefcallback_filter(clone_match_func *filter, clone_callback_func *p)
+{
+ struct clone_defcb *dcp;
+
+ dcp = malloc(sizeof(*dcp));
+ dcp->ifmatch = filter;
+ dcp->clone_mt = MT_FILTER;
dcp->clone_cb = p;
SLIST_INSERT_HEAD(&clone_defcbh, dcp, next);
}
@@ -114,8 +136,14 @@ ifclonecreate(int s, void *arg)
if (clone_cb == NULL) {
/* Try to find a default callback */
SLIST_FOREACH(dcp, &clone_defcbh, next) {
- if (strncmp(dcp->ifprefix, ifr.ifr_name,
- strlen(dcp->ifprefix)) == 0) {
+ if ((dcp->clone_mt == MT_PREFIX) &&
+ (strncmp(dcp->ifprefix, ifr.ifr_name,
+ strlen(dcp->ifprefix)) == 0)) {
+ clone_cb = dcp->clone_cb;
+ break;
+ }
+ if ((dcp->clone_mt == MT_FILTER) &&
+ dcp->ifmatch(ifr.ifr_name)) {
clone_cb = dcp->clone_cb;
break;
}