Commit 117aef12 authored by Alexander Lobakin's avatar Alexander Lobakin Committed by David S. Miller
Browse files

ip_tunnel: use a separate struct to store tunnel params in the kernel



Unlike IPv6 tunnels which use purely-kernel __ip6_tnl_parm structure
to store params inside the kernel, IPv4 tunnel code uses the same
ip_tunnel_parm which is being used to talk with the userspace.
This makes it difficult to alter or add any fields or use a
different format for whatever data.
Define struct ip_tunnel_parm_kern, a 1:1 copy of ip_tunnel_parm for
now, and use it throughout the code. Define the pieces, where the copy
user <-> kernel happens, as standalone functions, and copy the data
there field-by-field, so that the kernel-side structure could be easily
modified later on and the users wouldn't have to care about this.

Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7adaf37f
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
#include "spectrum_ipip.h"
#include "reg.h"

struct ip_tunnel_parm
struct ip_tunnel_parm_kern
mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev)
{
	struct ip_tunnel *tun = netdev_priv(ol_dev);
@@ -24,7 +24,8 @@ mlxsw_sp_ipip_netdev_parms6(const struct net_device *ol_dev)
	return tun->parms;
}

static bool mlxsw_sp_ipip_parms4_has_ikey(const struct ip_tunnel_parm *parms)
static bool
mlxsw_sp_ipip_parms4_has_ikey(const struct ip_tunnel_parm_kern *parms)
{
	return !!(parms->i_flags & TUNNEL_KEY);
}
@@ -34,7 +35,8 @@ static bool mlxsw_sp_ipip_parms6_has_ikey(const struct __ip6_tnl_parm *parms)
	return !!(parms->i_flags & TUNNEL_KEY);
}

static bool mlxsw_sp_ipip_parms4_has_okey(const struct ip_tunnel_parm *parms)
static bool
mlxsw_sp_ipip_parms4_has_okey(const struct ip_tunnel_parm_kern *parms)
{
	return !!(parms->o_flags & TUNNEL_KEY);
}
@@ -44,7 +46,7 @@ static bool mlxsw_sp_ipip_parms6_has_okey(const struct __ip6_tnl_parm *parms)
	return !!(parms->o_flags & TUNNEL_KEY);
}

static u32 mlxsw_sp_ipip_parms4_ikey(const struct ip_tunnel_parm *parms)
static u32 mlxsw_sp_ipip_parms4_ikey(const struct ip_tunnel_parm_kern *parms)
{
	return mlxsw_sp_ipip_parms4_has_ikey(parms) ?
		be32_to_cpu(parms->i_key) : 0;
@@ -56,7 +58,7 @@ static u32 mlxsw_sp_ipip_parms6_ikey(const struct __ip6_tnl_parm *parms)
		be32_to_cpu(parms->i_key) : 0;
}

static u32 mlxsw_sp_ipip_parms4_okey(const struct ip_tunnel_parm *parms)
static u32 mlxsw_sp_ipip_parms4_okey(const struct ip_tunnel_parm_kern *parms)
{
	return mlxsw_sp_ipip_parms4_has_okey(parms) ?
		be32_to_cpu(parms->o_key) : 0;
@@ -69,7 +71,7 @@ static u32 mlxsw_sp_ipip_parms6_okey(const struct __ip6_tnl_parm *parms)
}

static union mlxsw_sp_l3addr
mlxsw_sp_ipip_parms4_saddr(const struct ip_tunnel_parm *parms)
mlxsw_sp_ipip_parms4_saddr(const struct ip_tunnel_parm_kern *parms)
{
	return (union mlxsw_sp_l3addr) { .addr4 = parms->iph.saddr };
}
@@ -81,7 +83,7 @@ mlxsw_sp_ipip_parms6_saddr(const struct __ip6_tnl_parm *parms)
}

static union mlxsw_sp_l3addr
mlxsw_sp_ipip_parms4_daddr(const struct ip_tunnel_parm *parms)
mlxsw_sp_ipip_parms4_daddr(const struct ip_tunnel_parm_kern *parms)
{
	return (union mlxsw_sp_l3addr) { .addr4 = parms->iph.daddr };
}
@@ -96,7 +98,7 @@ union mlxsw_sp_l3addr
mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
			   const struct net_device *ol_dev)
{
	struct ip_tunnel_parm parms4;
	struct ip_tunnel_parm_kern parms4;
	struct __ip6_tnl_parm parms6;

	switch (proto) {
@@ -115,7 +117,9 @@ mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
static __be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev)
{

	struct ip_tunnel_parm parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
	struct ip_tunnel_parm_kern parms4;

	parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);

	return mlxsw_sp_ipip_parms4_daddr(&parms4).addr4;
}
@@ -124,7 +128,7 @@ static union mlxsw_sp_l3addr
mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto,
			   const struct net_device *ol_dev)
{
	struct ip_tunnel_parm parms4;
	struct ip_tunnel_parm_kern parms4;
	struct __ip6_tnl_parm parms6;

	switch (proto) {
@@ -150,7 +154,7 @@ bool mlxsw_sp_l3addr_is_zero(union mlxsw_sp_l3addr addr)
static struct mlxsw_sp_ipip_parms
mlxsw_sp_ipip_netdev_parms_init_gre4(const struct net_device *ol_dev)
{
	struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);
	struct ip_tunnel_parm_kern parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);

	return (struct mlxsw_sp_ipip_parms) {
		.proto = MLXSW_SP_L3_PROTO_IPV4,
@@ -187,8 +191,8 @@ mlxsw_sp_ipip_decap_config_gre4(struct mlxsw_sp *mlxsw_sp,
{
	u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
	u16 ul_rif_id = mlxsw_sp_ipip_lb_ul_rif_id(ipip_entry->ol_lb);
	struct ip_tunnel_parm_kern parms;
	char rtdp_pl[MLXSW_REG_RTDP_LEN];
	struct ip_tunnel_parm parms;
	unsigned int type_check;
	bool has_ikey;
	u32 daddr4;
@@ -252,7 +256,7 @@ static struct mlxsw_sp_rif_ipip_lb_config
mlxsw_sp_ipip_ol_loopback_config_gre4(struct mlxsw_sp *mlxsw_sp,
				      const struct net_device *ol_dev)
{
	struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);
	struct ip_tunnel_parm_kern parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);
	enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;

	lb_ipipt = mlxsw_sp_ipip_parms4_has_okey(&parms) ?
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
#include <linux/if_tunnel.h>
#include <net/ip6_tunnel.h>

struct ip_tunnel_parm
struct ip_tunnel_parm_kern
mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev);
struct __ip6_tnl_parm
mlxsw_sp_ipip_netdev_parms6(const struct net_device *ol_dev);
+2 −2
Original line number Diff line number Diff line
@@ -413,8 +413,8 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev,
			    __be32 *saddrp, __be32 *daddrp)
{
	struct ip_tunnel *tun = netdev_priv(to_dev);
	struct ip_tunnel_parm_kern parms;
	struct net_device *dev = NULL;
	struct ip_tunnel_parm parms;
	struct rtable *rt = NULL;
	struct flowi4 fl4;

@@ -451,7 +451,7 @@ mlxsw_sp_span_entry_gretap4_parms(struct mlxsw_sp *mlxsw_sp,
				  const struct net_device *to_dev,
				  struct mlxsw_sp_span_parms *sparmsp)
{
	struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
	struct ip_tunnel_parm_kern tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
	union mlxsw_sp_l3addr saddr = { .addr4 = tparm.iph.saddr };
	union mlxsw_sp_l3addr daddr = { .addr4 = tparm.iph.daddr };
	bool inherit_tos = tparm.iph.tos & 0x1;
+4 −3
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct ethtool_ops;
struct kernel_hwtstamp_config;
struct phy_device;
struct dsa_port;
struct ip_tunnel_parm;
struct ip_tunnel_parm_kern;
struct macsec_context;
struct macsec_ops;
struct netdev_name_node;
@@ -1327,7 +1327,7 @@ struct netdev_net_notifier {
 *	queue id bound to an AF_XDP socket. The flags field specifies if
 *	only RX, only Tx, or both should be woken up using the flags
 *	XDP_WAKEUP_RX and XDP_WAKEUP_TX.
 * int (*ndo_tunnel_ctl)(struct net_device *dev, struct ip_tunnel_parm *p,
 * int (*ndo_tunnel_ctl)(struct net_device *dev, struct ip_tunnel_parm_kern *p,
 *			 int cmd);
 *	Add, change, delete or get information on an IPv4 tunnel.
 * struct net_device *(*ndo_get_peer_dev)(struct net_device *dev);
@@ -1583,7 +1583,8 @@ struct net_device_ops {
	int			(*ndo_xsk_wakeup)(struct net_device *dev,
						  u32 queue_id, u32 flags);
	int			(*ndo_tunnel_ctl)(struct net_device *dev,
						  struct ip_tunnel_parm *p, int cmd);
						  struct ip_tunnel_parm_kern *p,
						  int cmd);
	struct net_device *	(*ndo_get_peer_dev)(struct net_device *dev);
	int                     (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx,
                                                         struct net_device_path *path);
+20 −5
Original line number Diff line number Diff line
@@ -110,6 +110,17 @@ struct ip_tunnel_prl_entry {

struct metadata_dst;

/* Kernel-side copy of ip_tunnel_parm */
struct ip_tunnel_parm_kern {
	char			name[IFNAMSIZ];
	int			link;
	__be16			i_flags;
	__be16			o_flags;
	__be32			i_key;
	__be32			o_key;
	struct iphdr		iph;
};

struct ip_tunnel {
	struct ip_tunnel __rcu	*next;
	struct hlist_node hash_node;
@@ -136,7 +147,7 @@ struct ip_tunnel {

	struct dst_cache dst_cache;

	struct ip_tunnel_parm parms;
	struct ip_tunnel_parm_kern parms;

	int		mlink;
	int		encap_hlen;	/* Encap header length (FOU,GUE) */
@@ -291,7 +302,11 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
		    const struct iphdr *tnl_params, const u8 protocol);
void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
		       const u8 proto, int tunnel_hlen);
int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm_kern *p,
		  int cmd);
bool ip_tunnel_parm_from_user(struct ip_tunnel_parm_kern *kp,
			      const void __user *data);
bool ip_tunnel_parm_to_user(void __user *data, struct ip_tunnel_parm_kern *kp);
int ip_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
			     void __user *data, int cmd);
int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict);
@@ -307,16 +322,16 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
		  const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
		  bool log_ecn_error);
int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
			 struct ip_tunnel_parm *p, __u32 fwmark);
			 struct ip_tunnel_parm_kern *p, __u32 fwmark);
int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
		      struct ip_tunnel_parm *p, __u32 fwmark);
		      struct ip_tunnel_parm_kern *p, __u32 fwmark);
void ip_tunnel_setup(struct net_device *dev, unsigned int net_id);

bool ip_tunnel_netlink_encap_parms(struct nlattr *data[],
				   struct ip_tunnel_encap *encap);

void ip_tunnel_netlink_parms(struct nlattr *data[],
			     struct ip_tunnel_parm *parms);
			     struct ip_tunnel_parm_kern *parms);

extern const struct header_ops ip_tunnel_header_ops;
__be16 ip_tunnel_parse_protocol(const struct sk_buff *skb);
Loading