Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d24ad3fc authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bpf-next'



Daniel Borkmann says:

====================
BPF updates

Couple of misc updates to BPF, besides others this series adds
bpf_csum_diff() to be used with L3 csums, allows for managing
tunnel options for collect meta data mode, and enabling ipv6
traffic class for collect meta data in vxlan specifically (geneve
already supports it). For more details, please see individual
patches.

The series requires net to be merged into net-next first to
avoid any further pending merge conflicts.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 810813c4 1400615d
Loading
Loading
Loading
Loading
+4 −6
Original line number Original line Diff line number Diff line
@@ -775,10 +775,10 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
				       struct flowi4 *fl4,
				       struct flowi4 *fl4,
				       struct ip_tunnel_info *info)
				       struct ip_tunnel_info *info)
{
{
	bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
	struct geneve_dev *geneve = netdev_priv(dev);
	struct geneve_dev *geneve = netdev_priv(dev);
	struct dst_cache *dst_cache;
	struct dst_cache *dst_cache;
	struct rtable *rt = NULL;
	struct rtable *rt = NULL;
	bool use_cache = true;
	__u8 tos;
	__u8 tos;


	memset(fl4, 0, sizeof(*fl4));
	memset(fl4, 0, sizeof(*fl4));
@@ -804,7 +804,6 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
		dst_cache = &geneve->dst_cache;
		dst_cache = &geneve->dst_cache;
	}
	}


	use_cache = use_cache && !skb->mark;
	if (use_cache) {
	if (use_cache) {
		rt = dst_cache_get_ip4(dst_cache, &fl4->saddr);
		rt = dst_cache_get_ip4(dst_cache, &fl4->saddr);
		if (rt)
		if (rt)
@@ -832,11 +831,11 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
					   struct flowi6 *fl6,
					   struct flowi6 *fl6,
					   struct ip_tunnel_info *info)
					   struct ip_tunnel_info *info)
{
{
	bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
	struct geneve_dev *geneve = netdev_priv(dev);
	struct geneve_dev *geneve = netdev_priv(dev);
	struct geneve_sock *gs6 = geneve->sock6;
	struct geneve_sock *gs6 = geneve->sock6;
	struct dst_entry *dst = NULL;
	struct dst_entry *dst = NULL;
	struct dst_cache *dst_cache;
	struct dst_cache *dst_cache;
	bool use_cache = true;
	__u8 prio;
	__u8 prio;


	memset(fl6, 0, sizeof(*fl6));
	memset(fl6, 0, sizeof(*fl6));
@@ -862,7 +861,6 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
		dst_cache = &geneve->dst_cache;
		dst_cache = &geneve->dst_cache;
	}
	}


	use_cache = use_cache && !skb->mark;
	if (use_cache) {
	if (use_cache) {
		dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);
		dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);
		if (dst)
		if (dst)
@@ -940,7 +938,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
		u8 vni[3];
		u8 vni[3];


		tunnel_id_to_vni(key->tun_id, vni);
		tunnel_id_to_vni(key->tun_id, vni);
		if (key->tun_flags & TUNNEL_GENEVE_OPT)
		if (info->options_len)
			opts = ip_tunnel_info_opts(info);
			opts = ip_tunnel_info_opts(info);


		if (key->tun_flags & TUNNEL_CSUM)
		if (key->tun_flags & TUNNEL_CSUM)
@@ -1027,7 +1025,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
		u8 vni[3];
		u8 vni[3];


		tunnel_id_to_vni(key->tun_id, vni);
		tunnel_id_to_vni(key->tun_id, vni);
		if (key->tun_flags & TUNNEL_GENEVE_OPT)
		if (info->options_len)
			opts = ip_tunnel_info_opts(info);
			opts = ip_tunnel_info_opts(info);


		if (key->tun_flags & TUNNEL_CSUM)
		if (key->tun_flags & TUNNEL_CSUM)
+21 −17
Original line number Original line Diff line number Diff line
@@ -1756,17 +1756,15 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan,
				      struct sk_buff *skb, int oif, u8 tos,
				      struct sk_buff *skb, int oif, u8 tos,
				      __be32 daddr, __be32 *saddr,
				      __be32 daddr, __be32 *saddr,
				      struct dst_cache *dst_cache,
				      struct dst_cache *dst_cache,
				      struct ip_tunnel_info *info)
				      const struct ip_tunnel_info *info)
{
{
	bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
	struct rtable *rt = NULL;
	struct rtable *rt = NULL;
	bool use_cache = false;
	struct flowi4 fl4;
	struct flowi4 fl4;


	/* when the ip_tunnel_info is availble, the tos used for lookup is
	if (tos && !info)
	 * packet independent, so we can use the cache
		use_cache = false;
	 */
	if (use_cache) {
	if (!skb->mark && (!tos || info)) {
		use_cache = true;
		rt = dst_cache_get_ip4(dst_cache, saddr);
		rt = dst_cache_get_ip4(dst_cache, saddr);
		if (rt)
		if (rt)
			return rt;
			return rt;
@@ -1791,16 +1789,20 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan,


#if IS_ENABLED(CONFIG_IPV6)
#if IS_ENABLED(CONFIG_IPV6)
static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
					  struct sk_buff *skb, int oif,
					  struct sk_buff *skb, int oif, u8 tos,
					  const struct in6_addr *daddr,
					  const struct in6_addr *daddr,
					  struct in6_addr *saddr,
					  struct in6_addr *saddr,
					  struct dst_cache *dst_cache)
					  struct dst_cache *dst_cache,
					  const struct ip_tunnel_info *info)
{
{
	bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
	struct dst_entry *ndst;
	struct dst_entry *ndst;
	struct flowi6 fl6;
	struct flowi6 fl6;
	int err;
	int err;


	if (!skb->mark) {
	if (tos && !info)
		use_cache = false;
	if (use_cache) {
		ndst = dst_cache_get_ip6(dst_cache, saddr);
		ndst = dst_cache_get_ip6(dst_cache, saddr);
		if (ndst)
		if (ndst)
			return ndst;
			return ndst;
@@ -1808,6 +1810,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,


	memset(&fl6, 0, sizeof(fl6));
	memset(&fl6, 0, sizeof(fl6));
	fl6.flowi6_oif = oif;
	fl6.flowi6_oif = oif;
	fl6.flowi6_tos = RT_TOS(tos);
	fl6.daddr = *daddr;
	fl6.daddr = *daddr;
	fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
	fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
	fl6.flowi6_mark = skb->mark;
	fl6.flowi6_mark = skb->mark;
@@ -1820,7 +1823,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
		return ERR_PTR(err);
		return ERR_PTR(err);


	*saddr = fl6.saddr;
	*saddr = fl6.saddr;
	if (!skb->mark)
	if (use_cache)
		dst_cache_set_ip6(dst_cache, ndst, saddr);
		dst_cache_set_ip6(dst_cache, ndst, saddr);
	return ndst;
	return ndst;
}
}
@@ -2016,9 +2019,9 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		sk = vxlan->vn6_sock->sock->sk;
		sk = vxlan->vn6_sock->sock->sk;


		ndst = vxlan6_get_route(vxlan, skb,
		ndst = vxlan6_get_route(vxlan, skb,
					rdst ? rdst->remote_ifindex : 0,
					rdst ? rdst->remote_ifindex : 0, tos,
					&dst->sin6.sin6_addr, &saddr,
					&dst->sin6.sin6_addr, &saddr,
					dst_cache);
					dst_cache, info);
		if (IS_ERR(ndst)) {
		if (IS_ERR(ndst)) {
			netdev_dbg(dev, "no route to %pI6\n",
			netdev_dbg(dev, "no route to %pI6\n",
				   &dst->sin6.sin6_addr);
				   &dst->sin6.sin6_addr);
@@ -2053,6 +2056,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		if (!info)
		if (!info)
			udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
			udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);


		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
		ttl = ttl ? : ip6_dst_hoplimit(ndst);
		ttl = ttl ? : ip6_dst_hoplimit(ndst);
		skb_scrub_packet(skb, xnet);
		skb_scrub_packet(skb, xnet);
		err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
		err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
@@ -2062,8 +2066,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
			return;
			return;
		}
		}
		udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
		udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
				     &saddr, &dst->sin6.sin6_addr,
				     &saddr, &dst->sin6.sin6_addr, tos, ttl,
				     0, ttl, src_port, dst_port, !udp_sum);
				     src_port, dst_port, !udp_sum);
#endif
#endif
	}
	}


@@ -2385,9 +2389,9 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)


		if (!vxlan->vn6_sock)
		if (!vxlan->vn6_sock)
			return -EINVAL;
			return -EINVAL;
		ndst = vxlan6_get_route(vxlan, skb, 0,
		ndst = vxlan6_get_route(vxlan, skb, 0, info->key.tos,
					&info->key.u.ipv6.dst,
					&info->key.u.ipv6.dst,
					&info->key.u.ipv6.src, NULL);
					&info->key.u.ipv6.src, NULL, info);
		if (IS_ERR(ndst))
		if (IS_ERR(ndst))
			return PTR_ERR(ndst);
			return PTR_ERR(ndst);
		dst_release(ndst);
		dst_release(ndst);
+5 −0
Original line number Original line Diff line number Diff line
@@ -120,6 +120,11 @@ static inline __wsum csum_partial_ext(const void *buff, int len, __wsum sum)


#define CSUM_MANGLED_0 ((__force __sum16)0xffff)
#define CSUM_MANGLED_0 ((__force __sum16)0xffff)


static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff)
{
	*sum = csum_fold(csum_add(diff, ~csum_unfold(*sum)));
}

static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
{
{
	__wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from);
	__wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from);
+15 −0
Original line number Original line Diff line number Diff line
@@ -140,6 +140,7 @@ struct ip_tunnel {
#define TUNNEL_CRIT_OPT		__cpu_to_be16(0x0400)
#define TUNNEL_CRIT_OPT		__cpu_to_be16(0x0400)
#define TUNNEL_GENEVE_OPT	__cpu_to_be16(0x0800)
#define TUNNEL_GENEVE_OPT	__cpu_to_be16(0x0800)
#define TUNNEL_VXLAN_OPT	__cpu_to_be16(0x1000)
#define TUNNEL_VXLAN_OPT	__cpu_to_be16(0x1000)
#define TUNNEL_NOCACHE		__cpu_to_be16(0x2000)


#define TUNNEL_OPTIONS_PRESENT	(TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)
#define TUNNEL_OPTIONS_PRESENT	(TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)


@@ -206,6 +207,20 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
		       0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
		       0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
}
}


static inline bool
ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
			   const struct ip_tunnel_info *info)
{
	if (skb->mark)
		return false;
	if (!info)
		return true;
	if (info->key.tun_flags & TUNNEL_NOCACHE)
		return false;

	return true;
}

static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
					       *tun_info)
					       *tun_info)
{
{
+13 −0
Original line number Original line Diff line number Diff line
@@ -298,6 +298,17 @@ enum bpf_func_id {
	 * Return: csum result
	 * Return: csum result
	 */
	 */
	BPF_FUNC_csum_diff,
	BPF_FUNC_csum_diff,

	/**
	 * bpf_skb_[gs]et_tunnel_opt(skb, opt, size)
	 * retrieve or populate tunnel options metadata
	 * @skb: pointer to skb
	 * @opt: pointer to raw tunnel option data
	 * @size: size of @opt
	 * Return: 0 on success for set, option size for get
	 */
	BPF_FUNC_skb_get_tunnel_opt,
	BPF_FUNC_skb_set_tunnel_opt,
	__BPF_FUNC_MAX_ID,
	__BPF_FUNC_MAX_ID,
};
};


@@ -305,6 +316,7 @@ enum bpf_func_id {


/* BPF_FUNC_skb_store_bytes flags. */
/* BPF_FUNC_skb_store_bytes flags. */
#define BPF_F_RECOMPUTE_CSUM		(1ULL << 0)
#define BPF_F_RECOMPUTE_CSUM		(1ULL << 0)
#define BPF_F_INVALIDATE_HASH		(1ULL << 1)


/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.
/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.
 * First 4 bits are for passing the header field size.
 * First 4 bits are for passing the header field size.
@@ -329,6 +341,7 @@ enum bpf_func_id {


/* BPF_FUNC_skb_set_tunnel_key flags. */
/* BPF_FUNC_skb_set_tunnel_key flags. */
#define BPF_F_ZERO_CSUM_TX		(1ULL << 1)
#define BPF_F_ZERO_CSUM_TX		(1ULL << 1)
#define BPF_F_DONT_FRAGMENT		(1ULL << 2)


/* user accessible mirror of in-kernel sk_buff.
/* user accessible mirror of in-kernel sk_buff.
 * new fields can only be added to the end of this structure
 * new fields can only be added to the end of this structure
Loading