Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142138324
D51243.id159444.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D51243.id159444.diff
View Options
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -435,43 +435,80 @@
err(1, "BRDGFLUSH");
}
-static void
-setbridge_static(if_ctx *ctx, const char *val, const char *mac)
+static int
+setbridge_static(if_ctx *ctx, int argc, const char *const *argv)
{
struct ifbareq req;
struct ether_addr *ea;
+ int arg;
+
+ if (argc < 2)
+ errx(1, "usage: static <interface> <address> [vlan <id>]");
+ arg = 0;
memset(&req, 0, sizeof(req));
- strlcpy(req.ifba_ifsname, val, sizeof(req.ifba_ifsname));
+ req.ifba_flags = IFBAF_STATIC;
- ea = ether_aton(mac);
- if (ea == NULL)
- errx(1, "%s: invalid address: %s", val, mac);
+ strlcpy(req.ifba_ifsname, argv[arg], sizeof(req.ifba_ifsname));
+ ++arg;
+ ea = ether_aton(argv[arg]);
+ if (ea == NULL)
+ errx(1, "invalid address: %s", argv[arg]);
memcpy(req.ifba_dst, ea->octet, sizeof(req.ifba_dst));
- req.ifba_flags = IFBAF_STATIC;
- req.ifba_vlan = 0; /* XXX allow user to specify */
+ ++arg;
+
+ req.ifba_vlan = 0;
+ if (argc > 2 && strcmp(argv[arg], "vlan") == 0) {
+ if (argc < 3)
+ errx(1, "usage: static <interface> <address> "
+ "[vlan <id>]");
+ ++arg;
+
+ if (get_vlan_id(argv[arg], &req.ifba_vlan) < 0)
+ errx(1, "invalid vlan id: %s", argv[arg]);
+ ++arg;
+ }
if (do_cmd(ctx, BRDGSADDR, &req, sizeof(req), 1) < 0)
- err(1, "BRDGSADDR %s", val);
+ err(1, "BRDGSADDR");
+ return arg;
}
-static void
-setbridge_deladdr(if_ctx *ctx, const char *val, int dummy __unused)
+static int
+setbridge_deladdr(if_ctx *ctx, int argc, const char *const *argv)
{
struct ifbareq req;
struct ether_addr *ea;
+ int arg;
+
+ if (argc < 1)
+ errx(1, "usage: deladdr <address> [vlan <id>]");
+ arg = 0;
memset(&req, 0, sizeof(req));
- ea = ether_aton(val);
+ ea = ether_aton(argv[arg]);
if (ea == NULL)
- errx(1, "invalid address: %s", val);
-
+ errx(1, "invalid address: %s", argv[arg]);
memcpy(req.ifba_dst, ea->octet, sizeof(req.ifba_dst));
+ ++arg;
+
+ req.ifba_vlan = 0;
+ if (argc >= 2 && strcmp(argv[arg], "vlan") == 0) {
+ if (argc < 3)
+ errx(1, "usage: deladdr <address> [vlan <id>]");
+ ++arg;
+
+ if (get_vlan_id(argv[arg], &req.ifba_vlan) < 0)
+ errx(1, "invalid vlan id: %s", argv[arg]);
+ ++arg;
+ }
if (do_cmd(ctx, BRDGDADDR, &req, sizeof(req), 1) < 0)
- err(1, "BRDGDADDR %s", val);
+ err(1, "BRDGDADDR");
+
+ return arg;
}
static void
@@ -824,8 +861,8 @@
DEF_CMD_ARG("-autoptp", unsetbridge_autoptp),
DEF_CMD("flush", 0, setbridge_flush),
DEF_CMD("flushall", 0, setbridge_flushall),
- DEF_CMD_ARG2("static", setbridge_static),
- DEF_CMD_ARG("deladdr", setbridge_deladdr),
+ DEF_CMD_VARG("static", setbridge_static),
+ DEF_CMD_VARG("deladdr", setbridge_deladdr),
DEF_CMD("addr", 1, setbridge_addr),
DEF_CMD_ARG("maxaddr", setbridge_maxaddr),
DEF_CMD_ARG("hellotime", setbridge_hellotime),
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -67,6 +67,7 @@
typedef void c_func(if_ctx *ctx, const char *cmd, int arg);
typedef void c_func2(if_ctx *ctx, const char *arg1, const char *arg2);
typedef void c_func3(if_ctx *ctx, const char *cmd, const char *arg);
+typedef int c_funcv(if_ctx *ctx, int argc, const char *const *argv);
struct cmd {
const char *c_name;
@@ -75,11 +76,13 @@
#define NEXTARG2 0xfffffe /* has 2 following args */
#define OPTARG 0xfffffd /* has optional following arg */
#define SPARAM 0xfffffc /* parameter is string c_sparameter */
+#define ARGVECTOR 0xfffffb /* takes argument vector */
const char *c_sparameter;
union {
c_func *c_func;
c_func2 *c_func2;
c_func3 *c_func3;
+ c_funcv *c_funcv;
} c_u;
int c_iscloneop;
struct cmd *c_next;
@@ -121,6 +124,13 @@
.c_iscloneop = 0, \
.c_next = NULL, \
}
+#define DEF_CMD_VARG(name, func) { \
+ .c_name = (name), \
+ .c_parameter = ARGVECTOR, \
+ .c_u = { .c_funcv = (func) }, \
+ .c_iscloneop = 0, \
+ .c_next = NULL, \
+}
#define DEF_CMD_SARG(name, sparam, func) { \
.c_name = (name), \
.c_parameter = SPARAM, \
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 14, 2025
+.Dd July 30, 2025
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -2520,15 +2520,23 @@
The default is 1200 seconds.
.It Cm addr
Display the addresses that have been learned by the bridge.
-.It Cm static Ar interface-name Ar address
-Add a static entry into the address cache pointing to
+.It Cm static Ar interface-name Ar address Op Cm vlan Ar vlan-id
+Add a static entry into the address cache for pointing to
.Ar interface-name .
+If
+.Ar vlan-id
+is specified, the entry is added for that VLAN, otherwise it is added
+for VLAN 0.
+.Pp
Static entries are never aged out of the cache or re-placed, even if the
address is seen on a different interface.
-.It Cm deladdr Ar address
+.It Cm deladdr Ar address Op Cm vlan Ar vlan-id
Delete
.Ar address
-from the address cache.
+from the address cache. If
+.Ar vlan-id
+is specified, the entry is deleted from that VLAN's address table,
+otherwise it is deleted from the VLAN 0 address table.
.It Cm flush
Delete all dynamically-learned addresses from the address cache.
.It Cm flushall
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1209,6 +1209,13 @@
argc -= 2, argv += 2;
} else if (p->c_parameter == SPARAM && p->c_u.c_func3) {
p->c_u.c_func3(ctx, *argv, p->c_sparameter);
+ } else if (p->c_parameter == ARGVECTOR && p->c_u.c_funcv) {
+ int argsdone;
+
+ argsdone = p->c_u.c_funcv(ctx, argc - 1,
+ (const char *const *)argv + 1);
+ argc -= argsdone;
+ argv += argsdone;
} else if (p->c_u.c_func)
p->c_u.c_func(ctx, *argv, p->c_parameter);
argc--, argv++;
diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh
--- a/tests/sys/net/if_bridge_test.sh
+++ b/tests/sys/net/if_bridge_test.sh
@@ -245,7 +245,8 @@
jexec one ifconfig ${bridge} static ${epair}a 00:01:02:03:04:05
# List addresses
- atf_check -s exit:0 -o ignore \
+ atf_check -s exit:0 \
+ -o match:"00:01:02:03:04:05 Vlan0 ${epair}a 0 flags=1<STATIC>" \
jexec one ifconfig ${bridge} addr
# Delete with bad address format
@@ -266,6 +267,72 @@
vnet_cleanup
}
+atf_test_case "vstatic" "cleanup"
+vstatic_head()
+{
+ atf_set descr 'Bridge VLAN static address test'
+ atf_set require.user root
+}
+
+vstatic_body()
+{
+ vnet_init
+ vnet_init_bridge
+
+ epair=$(vnet_mkepair)
+ bridge=$(vnet_mkbridge)
+
+ vnet_mkjail one ${bridge} ${epair}a
+
+ ifconfig ${epair}b up
+
+ jexec one ifconfig ${bridge} up
+ jexec one ifconfig ${epair}a up
+ jexec one ifconfig ${bridge} addm ${epair}a
+
+ # Wrong interface
+ atf_check -s exit:1 -o ignore -e ignore jexec one \
+ ifconfig ${bridge} static ${epair}b 00:01:02:03:04:05 vlan 10
+
+ # Bad address format
+ atf_check -s exit:1 -o ignore -e ignore jexec one \
+ ifconfig ${bridge} static ${epair}a 00:01:02:03:04 vlan 10
+
+ # Invalid VLAN ID
+ atf_check -s exit:1 -o ignore -e ignore jexec one \
+ ifconfig ${bridge} static ${epair}a 00:01:02:03:04:05 vlan 5000
+
+ # Correct add
+ atf_check -s exit:0 -o ignore jexec one \
+ ifconfig ${bridge} static ${epair}a 00:01:02:03:04:05 vlan 10
+
+ # List addresses
+ atf_check -s exit:0 \
+ -o match:"00:01:02:03:04:05 Vlan10 ${epair}a 0 flags=1<STATIC>" \
+ jexec one ifconfig ${bridge} addr
+
+ # Delete with bad address format
+ atf_check -s exit:1 -o ignore -e ignore jexec one \
+ ifconfig ${bridge} deladdr 00:01:02:03:04 vlan 10
+
+ # Delete with unlisted address
+ atf_check -s exit:1 -o ignore -e ignore jexec one \
+ ifconfig ${bridge} deladdr 00:01:02:03:04:06 vlan 10
+
+ # Delete with wrong vlan id
+ atf_check -s exit:1 -o ignore -e ignore jexec one \
+ ifconfig ${bridge} deladdr 00:01:02:03:04:05 vlan 20
+
+ # Correct delete
+ atf_check -s exit:0 -o ignore jexec one \
+ ifconfig ${bridge} deladdr 00:01:02:03:04:05 vlan 10
+}
+
+vstatic_cleanup()
+{
+ vnet_cleanup
+}
+
atf_test_case "span" "cleanup"
span_head()
{
@@ -1250,6 +1317,7 @@
atf_add_test_case "stp"
atf_add_test_case "stp_vlan"
atf_add_test_case "static"
+ atf_add_test_case "vstatic"
atf_add_test_case "span"
atf_add_test_case "inherit_mac"
atf_add_test_case "delete_with_members"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 17, 9:44 AM (6 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27688065
Default Alt Text
D51243.id159444.diff (8 KB)
Attached To
Mode
D51243: ifconfig: Support VLAN ID in static/deladdr
Attached
Detach File
Event Timeline
Log In to Comment