[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251120181248.3834304-4-skorodumov.dmitry@huawei.com>
Date: Thu, 20 Nov 2025 21:12:48 +0300
From: Dmitry Skorodumov <skorodumov.dmitry@...wei.com>
To: <netdev@...r.kernel.org>
CC: <stephen@...workplumber.org>, Dmitry Skorodumov
<skorodumov.dmitry@...wei.com>
Subject: [PATCH net-next 3/3] Support l2macnat in ip util
Supported mode l2macnat for ip add link type ipvlan/ipvtap
Mode was also described in man-page.
Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@...wei.com>
---
include/uapi/linux/if_link.h | 1 +
ip/iplink_ipvlan.c | 8 ++++++--
man/man8/ip-link.8.in | 11 ++++++++++-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index d05f5cc7..e17e684d 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -1267,6 +1267,7 @@ enum ipvlan_mode {
IPVLAN_MODE_L2 = 0,
IPVLAN_MODE_L3,
IPVLAN_MODE_L3S,
+ IPVLAN_MODE_L2_MACNAT,
IPVLAN_MODE_MAX
};
diff --git a/ip/iplink_ipvlan.c b/ip/iplink_ipvlan.c
index 691fd6f3..b80ab19b 100644
--- a/ip/iplink_ipvlan.c
+++ b/ip/iplink_ipvlan.c
@@ -19,7 +19,7 @@ static void print_explain(struct link_util *lu, FILE *f)
fprintf(f,
"Usage: ... %s [ mode MODE ] [ FLAGS ]\n"
"\n"
- "MODE: l3 | l3s | l2\n"
+ "MODE: l3 | l3s | l2 | l2macnat\n"
"FLAGS: bridge | private | vepa\n"
"(first values are the defaults if nothing is specified).\n",
lu->id);
@@ -29,6 +29,8 @@ static int get_ipvlan_mode(const char *mode)
{
if (strcmp(mode, "l2") == 0)
return IPVLAN_MODE_L2;
+ if (strcmp(mode, "l2macnat") == 0)
+ return IPVLAN_MODE_L2_MACNAT;
if (strcmp(mode, "l3") == 0)
return IPVLAN_MODE_L3;
if (strcmp(mode, "l3s") == 0)
@@ -41,6 +43,8 @@ static const char *get_ipvlan_mode_name(__u16 mode)
switch (mode) {
case IPVLAN_MODE_L2:
return "l2";
+ case IPVLAN_MODE_L2_MACNAT:
+ return "l2macnat";
case IPVLAN_MODE_L3:
return "l3";
case IPVLAN_MODE_L3S:
@@ -65,7 +69,7 @@ static int ipvlan_parse_opt(struct link_util *lu, int argc, char **argv,
mode = get_ipvlan_mode(*argv);
if (mode < 0) {
fprintf(stderr, "Error: argument of \"mode\" must be either "
- "\"l2\", \"l3\" or \"l3s\"\n");
+ "\"l2\", \"l2macnat\", \"l3\" or \"l3s\"\n");
return -1;
}
addattr16(n, 1024, IFLA_IPVLAN_MODE, (__u16)mode);
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index def83184..28fa2f7a 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1662,7 +1662,7 @@ the following additional arguments are supported:
.BI "ip link add link " MASTER " name " SLAVE
.BR type " { " ipvlan " | " ipvtap " } "
-.RB " [ " mode " { " l3 " | " l3s " | " l2 " } ] "
+.RB " [ " mode " { " l3 " | " l3s " | " l2 " | " l2macnat " } ] "
.RB " [ { " bridge " | " private " | " vepa " } ] "
.in +8
@@ -1690,6 +1690,15 @@ slave device and packets are switched and queued to the master device to send
out. In this mode the slaves will RX/TX multicast and broadcast (if applicable)
as well.
+.B mode l2macnat
+- This mode extends the L2 mode and is primarily designed for desktop virtual
+machines that need to bridge to wireless interfaces. In standard L2 mode,
+you must configure IP addresses on slave interfaces to enable frame
+multiplexing between slaves and the master. In
+.BR l2macnat
+mode, IPVLAN automatically learns IPv4/IPv6 and MAC addresses
+from outgoing packets.
+
.B bridge
- Default option. All endpoints are directly connected to each other,
communication is not redirected through the physical interface's peer.
--
2.25.1
Powered by blists - more mailing lists