Inherited features of olk5.10 version.
Keefe LIU (4): ipvlan: Introduce l2e mode ipvlan: check the value of module parameter ipvlan_default_mode ipvlan: Introduce local xmit queue for l2e mode ipvlan: limit loop_qlen ranges
Keefe Liu (1): ipvlan: limit loop_delay ranges
Lu Wei (1): ipvlan: Modify the value of ipvlan modes
drivers/net/ipvlan/ipvlan.h | 7 + drivers/net/ipvlan/ipvlan_core.c | 222 +++++++++++++++++++++++++++++++ drivers/net/ipvlan/ipvlan_main.c | 85 +++++++++++- include/uapi/linux/if_link.h | 1 + 4 files changed, 314 insertions(+), 1 deletion(-)
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/3095 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/R...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/3095 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/R...
From: Keefe LIU liuqifa@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8KDQE CVE: NA
-------------------------------------------------
In a typical IPvlan L2 setup where master is in default-ns and each slave is into different (slave) ns. In this setup, if master and slaves in different net, egress packet processing for traffic originating from slave-ns can't be forwarded to master or other machine whose ip in the same net with master, and they can't be forwarded to other interface in default-ns.
This patch introuce a new mode l2e for ipvlan to realize above goals, and it won't affect the original l2, l3, l3s mode.
As the ip tool doesn't support l2e mode, We use module param "ipvlan_default_mode" to set the default work mode. 0 for l2 mode, 1 for l3, 2 for l2e, 3 for l3s, others invalid now. Attention, when we create ipvlan devices by "ip" commond, if we assign the mode, ipvlan will work in the mode we assigned other then the "ipvlan_default_mode".
Signed-off-by: Keefe LIU liuqifa@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com
Modified: when insmod the ipvlan module, the origin version(4.19) is 0 for l2, 1 for l3, 2 for l2e, 3 for l3s mode, but in 5.10 version is 0 for l2, 1 for l3, 2 for l3s, 3 for l2e mode.
Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com
Modified: 6.6 version keeps the usage of 5.10 version
Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- drivers/net/ipvlan/ipvlan_core.c | 190 +++++++++++++++++++++++++++++++ drivers/net/ipvlan/ipvlan_main.c | 6 +- include/uapi/linux/if_link.h | 1 + 3 files changed, 196 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 21e9cac73121..0c7cad0e1608 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -538,6 +538,122 @@ static int ipvlan_process_outbound(struct sk_buff *skb) return ret; }
+static int ipvlan_process_v4_forward(struct sk_buff *skb) +{ + const struct iphdr *ip4h = ip_hdr(skb); + struct net_device *dev = skb->dev; + struct net *net = dev_net(dev); + struct rtable *rt; + int err, ret = NET_XMIT_DROP; + struct flowi4 fl4 = { + .flowi4_tos = RT_TOS(ip4h->tos), + .flowi4_flags = FLOWI_FLAG_ANYSRC, + .flowi4_mark = skb->mark, + .daddr = ip4h->daddr, + .saddr = ip4h->saddr, + }; + + rt = ip_route_output_flow(net, &fl4, NULL); + if (IS_ERR(rt)) + goto err; + + if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) { + ip_rt_put(rt); + goto err; + } + skb_dst_set(skb, &rt->dst); + err = ip_local_out(net, skb->sk, skb); + if (unlikely(net_xmit_eval(err))) + dev->stats.tx_errors++; + else + ret = NET_XMIT_SUCCESS; + goto out; +err: + dev->stats.tx_errors++; + kfree_skb(skb); +out: + return ret; +} + +#if IS_ENABLED(CONFIG_IPV6) +static int ipvlan_process_v6_forward(struct sk_buff *skb) +{ + const struct ipv6hdr *ip6h = ipv6_hdr(skb); + struct net_device *dev = skb->dev; + struct net *net = dev_net(dev); + struct dst_entry *dst; + int err, ret = NET_XMIT_DROP; + struct flowi6 fl6 = { + .daddr = ip6h->daddr, + .saddr = ip6h->saddr, + .flowi6_flags = FLOWI_FLAG_ANYSRC, + .flowlabel = ip6_flowinfo(ip6h), + .flowi6_mark = skb->mark, + .flowi6_proto = ip6h->nexthdr, + }; + + dst = ip6_route_output(net, NULL, &fl6); + if (dst->error) { + ret = dst->error; + dst_release(dst); + goto err; + } + skb_dst_set(skb, dst); + err = ip6_local_out(net, skb->sk, skb); + if (unlikely(net_xmit_eval(err))) + dev->stats.tx_errors++; + else + ret = NET_XMIT_SUCCESS; + goto out; +err: + dev->stats.tx_errors++; + kfree_skb(skb); +out: + return ret; +} +#else +static int ipvlan_process_v6_forward(struct sk_buff *skb) +{ + return NET_XMIT_DROP; +} +#endif + +static int ipvlan_process_forward(struct sk_buff *skb) +{ + struct ethhdr *ethh = eth_hdr(skb); + int ret = NET_XMIT_DROP; + + /* In this mode we dont care about multicast and broadcast traffic */ + if (is_multicast_ether_addr(ethh->h_dest)) { + pr_debug_ratelimited("Dropped {multi|broad}cast of type=[%x]\n", + ntohs(skb->protocol)); + kfree_skb(skb); + goto out; + } + + /* The ipvlan is a pseudo-L2 device, so the packets that we receive + * will have L2; which need to discarded and processed further + * in the net-ns of the main-device. + */ + if (skb_mac_header_was_set(skb)) { + skb_pull(skb, sizeof(*ethh)); + skb->mac_header = (typeof(skb->mac_header))~0U; + skb_reset_network_header(skb); + } + + if (skb->protocol == htons(ETH_P_IPV6)) { + ret = ipvlan_process_v6_forward(skb); + } else if (skb->protocol == htons(ETH_P_IP)) { + ret = ipvlan_process_v4_forward(skb); + } else { + pr_warn_ratelimited("Dropped outbound packet type=%x\n", + ntohs(skb->protocol)); + kfree_skb(skb); + } +out: + return ret; +} + static void ipvlan_multicast_enqueue(struct ipvl_port *port, struct sk_buff *skb, bool tx_pkt) { @@ -638,6 +754,46 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) return dev_queue_xmit(skb); }
+static int ipvlan_xmit_mode_l2e(struct sk_buff *skb, struct net_device *dev) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ethhdr *eth = eth_hdr(skb); + struct ipvl_addr *addr; + void *lyr3h; + int addr_type; + + if (!ipvlan_is_vepa(ipvlan->port) && + ether_addr_equal(eth->h_dest, eth->h_source)) { + lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type); + if (lyr3h) { + addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, + addr_type, true); + if (addr) { + if (ipvlan_is_private(ipvlan->port)) { + consume_skb(skb); + return NET_XMIT_DROP; + } + return ipvlan_rcv_frame(addr, &skb, true); + } + } + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + return NET_XMIT_DROP; + + /* maybe the packet need been forward */ + skb->dev = ipvlan->phy_dev; + ipvlan_skb_crossing_ns(skb, ipvlan->phy_dev); + return ipvlan_process_forward(skb); + } else if (is_multicast_ether_addr(eth->h_dest)) { + ipvlan_skb_crossing_ns(skb, NULL); + ipvlan_multicast_enqueue(ipvlan->port, skb, true); + return NET_XMIT_SUCCESS; + } + + skb->dev = ipvlan->phy_dev; + return dev_queue_xmit(skb); +} + int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); @@ -657,6 +813,8 @@ int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) case IPVLAN_MODE_L3S: #endif return ipvlan_xmit_mode_l3(skb, dev); + case IPVLAN_MODE_L2E: + return ipvlan_xmit_mode_l2e(skb, dev); }
/* Should not reach here */ @@ -737,6 +895,36 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb, return ret; }
+static rx_handler_result_t ipvlan_handle_mode_l2e(struct sk_buff **pskb, + struct ipvl_port *port) +{ + struct sk_buff *skb = *pskb; + struct ethhdr *eth = eth_hdr(skb); + rx_handler_result_t ret = RX_HANDLER_PASS; + + if (is_multicast_ether_addr(eth->h_dest)) { + if (ipvlan_external_frame(skb, port)) { + struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); + + /* External frames are queued for device local + * distribution, but a copy is given to master + * straight away to avoid sending duplicates later + * when work-queue processes this frame. This is + * achieved by returning RX_HANDLER_PASS. + */ + if (nskb) { + ipvlan_skb_crossing_ns(nskb, NULL); + ipvlan_multicast_enqueue(port, nskb, false); + } + } + } else { + /* Perform like l3 mode for non-multicast packet */ + ret = ipvlan_handle_mode_l3(pskb, port); + } + + return ret; +} + rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb) { struct sk_buff *skb = *pskb; @@ -754,6 +942,8 @@ rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb) case IPVLAN_MODE_L3S: return RX_HANDLER_PASS; #endif + case IPVLAN_MODE_L2E: + return ipvlan_handle_mode_l2e(pskb, port); }
/* Should not reach here */ diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 57c79f5f2991..3c41ac1b8612 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -6,6 +6,10 @@
#include "ipvlan.h"
+static int ipvlan_default_mode = IPVLAN_MODE_L3; +module_param(ipvlan_default_mode, int, 0400); +MODULE_PARM_DESC(ipvlan_default_mode, "set ipvlan default mode: 0 for l2, 1 for l3, 2 for l3s, 3 for l2e, others invalid now"); + static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval, struct netlink_ext_ack *extack) { @@ -538,7 +542,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev, struct ipvl_port *port; struct net_device *phy_dev; int err; - u16 mode = IPVLAN_MODE_L3; + u16 mode = ipvlan_default_mode;
if (!tb[IFLA_LINK]) return -EINVAL; diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index ce3117df9cec..e603ada6b5ea 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -742,6 +742,7 @@ enum ipvlan_mode { IPVLAN_MODE_L2 = 0, IPVLAN_MODE_L3, IPVLAN_MODE_L3S, + IPVLAN_MODE_L2E, IPVLAN_MODE_MAX };
From: Keefe LIU liuqifa@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8KDQE CVE: NA
-------------------------------------------------
In commit <7a0f243de9e2> "ipvlan: Introduce l2e mode", we introduced ipvlan_default_mode as a way to enable the ipvlan's default mode. Howerver, we didn't check the value of this module parameter.
This patch first fixed out a spelling error of "mode", and then add the value check for ipvlan_default_mode.
Signed-off-by: Keefe LIU liuqifa@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- drivers/net/ipvlan/ipvlan_main.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 3c41ac1b8612..ff14b24ee8d3 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -1030,6 +1030,10 @@ static int __init ipvlan_init_module(void) { int err;
+ if (ipvlan_default_mode >= IPVLAN_MODE_MAX || + ipvlan_default_mode < IPVLAN_MODE_L2) + return -EINVAL; + ipvlan_init_secret(); register_netdevice_notifier(&ipvlan_notifier_block); #if IS_ENABLED(CONFIG_IPV6)
From: Keefe LIU liuqifa@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8KDQE CVE: NA
-------------------------------------------------
Consider two IPVlan devices are set up on the same master, when they communicate with each other by TCP, the receive part is too fast to make the send packets coalesced, so in this case, the performace is not as good as we expect.
This patch introduces a local xmit queue for l2e mode, when the packets are sent to the IPVlan devices of the same master, the packets will be cloned and added to the local xmit queue, this operation can make the send packets coalesced and improve the TCP performace in this case.
Signed-off-by: Keefe LIU liuqifa@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- drivers/net/ipvlan/ipvlan.h | 7 ++++ drivers/net/ipvlan/ipvlan_core.c | 34 ++++++++++++++++- drivers/net/ipvlan/ipvlan_main.c | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h index 025e0c19ec25..7b1a1f9c440f 100644 --- a/drivers/net/ipvlan/ipvlan.h +++ b/drivers/net/ipvlan/ipvlan.h @@ -39,6 +39,9 @@
#define IPVLAN_QBACKLOG_LIMIT 1000
+extern int sysctl_ipvlan_loop_qlen; +extern int sysctl_ipvlan_loop_delay; + typedef enum { IPVL_IPV6 = 0, IPVL_ICMPV6, @@ -70,6 +73,10 @@ struct ipvl_dev { netdev_features_t sfeatures; u32 msg_enable; spinlock_t addrs_lock; + int local_packets_cached; + unsigned long local_timeout; + struct timer_list local_free_timer; + struct sk_buff_head local_xmit_queue; };
struct ipvl_addr { diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 0c7cad0e1608..a13971f44ef0 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -754,9 +754,37 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) return dev_queue_xmit(skb); }
+static int ipvlan_l2e_local_xmit_event(struct ipvl_dev *ipvlan, + struct sk_buff **pskb) +{ + struct sk_buff *nskb, *tskb; + + while ((ipvlan->local_packets_cached >= sysctl_ipvlan_loop_qlen) && + (tskb = skb_dequeue(&ipvlan->local_xmit_queue))) { + ipvlan->local_packets_cached -= tskb->truesize; + if (ipvlan->local_packets_cached < 0 || + skb_queue_empty(&ipvlan->local_xmit_queue)) + ipvlan->local_packets_cached = 0; + kfree_skb(tskb); + } + + nskb = skb_clone(*pskb, GFP_ATOMIC); + if (!nskb) + return NET_XMIT_DROP; + + ipvlan->local_timeout = jiffies + + (sysctl_ipvlan_loop_delay * HZ) / 1000; + mod_timer(&ipvlan->local_free_timer, ipvlan->local_timeout); + skb_queue_tail(&ipvlan->local_xmit_queue, *pskb); + ipvlan->local_packets_cached += (*pskb)->truesize; + *pskb = nskb; + + return 0; +} + static int ipvlan_xmit_mode_l2e(struct sk_buff *skb, struct net_device *dev) { - const struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_dev *ipvlan = netdev_priv(dev); struct ethhdr *eth = eth_hdr(skb); struct ipvl_addr *addr; void *lyr3h; @@ -773,6 +801,10 @@ static int ipvlan_xmit_mode_l2e(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); return NET_XMIT_DROP; } + + if (unlikely(ipvlan_l2e_local_xmit_event(ipvlan, + &skb))) + return NET_XMIT_DROP; return ipvlan_rcv_frame(addr, &skb, true); } } diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index ff14b24ee8d3..637290e9cb59 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -6,10 +6,43 @@
#include "ipvlan.h"
+int sysctl_ipvlan_loop_qlen = 131072; +int sysctl_ipvlan_loop_delay = 10; static int ipvlan_default_mode = IPVLAN_MODE_L3; module_param(ipvlan_default_mode, int, 0400); MODULE_PARM_DESC(ipvlan_default_mode, "set ipvlan default mode: 0 for l2, 1 for l3, 2 for l3s, 3 for l2e, others invalid now");
+static struct ctl_table_header *ipvlan_table_hrd; +static struct ctl_table ipvlan_table[] = { + { + .procname = "loop_delay", + .data = &sysctl_ipvlan_loop_delay, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "loop_qlen", + .data = &sysctl_ipvlan_loop_qlen, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { } +}; + +static int ipvlan_sysctl_init(void) +{ + ipvlan_table_hrd = register_net_sysctl(&init_net, + "net/ipvlan", ipvlan_table); + return !ipvlan_table_hrd ? -ENOMEM : 0; +} + +static void ipvlan_sysctl_exit(void) +{ + unregister_net_sysctl_table(ipvlan_table_hrd); +} + static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval, struct netlink_ext_ack *extack) { @@ -166,6 +199,32 @@ static int ipvlan_init(struct net_device *dev) return 0; }
+static void ipvlan_local_free_handler(struct timer_list *t) +{ + struct ipvl_dev *ipvlan = from_timer(ipvlan, t, local_free_timer); + + skb_queue_purge(&ipvlan->local_xmit_queue); + ipvlan->local_packets_cached = 0; +} + +static inline void ipvlan_local_init(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + + ipvlan->local_packets_cached = 0; + skb_queue_head_init(&ipvlan->local_xmit_queue); + timer_setup(&ipvlan->local_free_timer, + ipvlan_local_free_handler, 0); +} + +static inline void ipvlan_local_uninit(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + + del_timer(&ipvlan->local_free_timer); + skb_queue_purge(&ipvlan->local_xmit_queue); +} + static void ipvlan_uninit(struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); @@ -191,6 +250,7 @@ static int ipvlan_open(struct net_device *dev) else dev->flags &= ~IFF_NOARP;
+ ipvlan_local_init(dev); rcu_read_lock(); list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) ipvlan_ht_addr_add(ipvlan, addr); @@ -208,6 +268,7 @@ static int ipvlan_stop(struct net_device *dev) dev_uc_unsync(phy_dev, dev); dev_mc_unsync(phy_dev, dev);
+ ipvlan_local_uninit(dev); rcu_read_lock(); list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) ipvlan_ht_addr_del(addr); @@ -1054,6 +1115,9 @@ static int __init ipvlan_init_module(void) goto error; }
+ err = ipvlan_sysctl_init(); + if (err < 0) + pr_err("ipvlan proc init failed, continue\n"); return 0; error: unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); @@ -1081,6 +1145,7 @@ static void __exit ipvlan_cleanup_module(void) unregister_inet6addr_validator_notifier( &ipvlan_addr6_vtor_notifier_block); #endif + ipvlan_sysctl_exit(); }
module_init(ipvlan_init_module);
From: Keefe Liu liuqifa@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8KDQE CVE: NA
-------------------------------------------------
In order to avoid integer overflow, we should limit the ranges of loop_delay value.
Fixes: f4661458116b ("ipvlan: Introduce local xmit queue for l2e mode") Signed-off-by: Keefe Liu liuqifa@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- drivers/net/ipvlan/ipvlan_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 637290e9cb59..135e1e0e3ac1 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -6,6 +6,9 @@
#include "ipvlan.h"
+static int one = 1; +static int delay_max = 100; + int sysctl_ipvlan_loop_qlen = 131072; int sysctl_ipvlan_loop_delay = 10; static int ipvlan_default_mode = IPVLAN_MODE_L3; @@ -19,7 +22,9 @@ static struct ctl_table ipvlan_table[] = { .data = &sysctl_ipvlan_loop_delay, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &one, + .extra2 = &delay_max, }, { .procname = "loop_qlen",
From: Keefe LIU liuqifa@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8KDQE CVE: NA
-------------------------------------------------
In order to avoid integer overflow, we should limit the ranges of loop_qlen value.
Fixes: 997518dea253 ("ipvlan: Introduce local xmit queue for l2e mode") Signed-off-by: Keefe Liu liuqifa@huawei.com Reviewed-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- drivers/net/ipvlan/ipvlan_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 135e1e0e3ac1..073e135cd9c9 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -8,6 +8,9 @@
static int one = 1; static int delay_max = 100; +/* set loop queue length from 0 to 10 big packets(65536) */ +static int qlen_min; +static int qlen_max = 655360;
int sysctl_ipvlan_loop_qlen = 131072; int sysctl_ipvlan_loop_delay = 10; @@ -31,7 +34,9 @@ static struct ctl_table ipvlan_table[] = { .data = &sysctl_ipvlan_loop_qlen, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &qlen_min, + .extra2 = &qlen_max, }, { } };
From: Lu Wei luwei32@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8KDQE CVE: NA
--------------------------------
The L2E mode of ipvlan is introduced in 4.19, and the mode value IPVLAN_MODE_L2E is inserted between IPVLAN_MODE_L3 and IPVLAN_MODE_L3S in enum ipvlan_mode as follows: enum ipvlan_mode { IPVLAN_MODE_L2 = 0, IPVLAN_MODE_L3, + IPVLAN_MODE_L2E, IPVLAN_MODE_L3S, IPVLAN_MODE_MAX };
that means the value of IPVLAN_MODE_L3S is changed from 2 to 3, and it is different from other operation system like SUSE, rethad and etc.
In order to fix it, IPVLAN_MODE_L2E is placed behind IPVLAN_MODE_L3S in 5.10. However it is incompatible with iproute tool since iproute defines enum ipvlan_mode as it does in 4.19. So this patch moves the IPVLAN_MODE_L2E back to keep incompatible with iproute tool.
Fixes: bd73acb1ae5a ("ipvlan: Introduce l2e mode") Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- drivers/net/ipvlan/ipvlan_main.c | 2 +- include/uapi/linux/if_link.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 073e135cd9c9..9a7cfe44b865 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -16,7 +16,7 @@ int sysctl_ipvlan_loop_qlen = 131072; int sysctl_ipvlan_loop_delay = 10; static int ipvlan_default_mode = IPVLAN_MODE_L3; module_param(ipvlan_default_mode, int, 0400); -MODULE_PARM_DESC(ipvlan_default_mode, "set ipvlan default mode: 0 for l2, 1 for l3, 2 for l3s, 3 for l2e, others invalid now"); +MODULE_PARM_DESC(ipvlan_default_mode, "set ipvlan default mode: 0 for l2, 1 for l3, 2 for l2e, 3 for l3s, others invalid now");
static struct ctl_table_header *ipvlan_table_hrd; static struct ctl_table ipvlan_table[] = { diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index e603ada6b5ea..96ecfe1709e0 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -741,8 +741,8 @@ enum { enum ipvlan_mode { IPVLAN_MODE_L2 = 0, IPVLAN_MODE_L3, - IPVLAN_MODE_L3S, IPVLAN_MODE_L2E, + IPVLAN_MODE_L3S, IPVLAN_MODE_MAX };