History

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. ====================

David S. Miller committed 10 years ago

Commit d24ad3f2 parents 810813c 14006157 files · +165 −45Browse files

Unified · Split

7 files
  1. drivers/net/geneve.c +4 −6
  2. drivers/net/vxlan.c +21 −17
  3. include/net/checksum.h +5 −0
  4. include/net/ip_tunnels.h +15 −0
  5. include/uapi/linux/bpf.h +13 −0
  6. net/core/filter.c +101 −18
  7. net/ipv4/ip_gre.c +6 −4
drivers/net/geneve.c+4−6
@@ -775,10 +775,10 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb, · 774 unmodified lines
775 struct flowi4 *fl4,775 struct flowi4 *fl4,
776 struct ip_tunnel_info *info)776 struct ip_tunnel_info *info)
777{777{
778 bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
778 struct geneve_dev *geneve = netdev_priv(dev);779 struct geneve_dev *geneve = netdev_priv(dev);
779 struct dst_cache *dst_cache;780 struct dst_cache *dst_cache;
780 struct rtable *rt = NULL;781 struct rtable *rt = NULL;
781 bool use_cache = true;
782 __u8 tos;782 __u8 tos;
783 783
784 memset(fl4, 0, sizeof(*fl4));784 memset(fl4, 0, sizeof(*fl4));
@@ -804,7 +804,6 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb, · 19 unmodified lines
804 dst_cache = &geneve->dst_cache;804 dst_cache = &geneve->dst_cache;
805 }805 }
806 806
807 use_cache = use_cache && !skb->mark;
808 if (use_cache) {807 if (use_cache) {
809 rt = dst_cache_get_ip4(dst_cache, &fl4->saddr);808 rt = dst_cache_get_ip4(dst_cache, &fl4->saddr);
810 if (rt)809 if (rt)
@@ -832,11 +831,11 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, · 21 unmodified lines
832 struct flowi6 *fl6,831 struct flowi6 *fl6,
833 struct ip_tunnel_info *info)832 struct ip_tunnel_info *info)
834{833{
834 bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
835 struct geneve_dev *geneve = netdev_priv(dev);835 struct geneve_dev *geneve = netdev_priv(dev);
836 struct geneve_sock *gs6 = geneve->sock6;836 struct geneve_sock *gs6 = geneve->sock6;
837 struct dst_entry *dst = NULL;837 struct dst_entry *dst = NULL;
838 struct dst_cache *dst_cache;838 struct dst_cache *dst_cache;
839 bool use_cache = true;
840 __u8 prio;839 __u8 prio;
841 840
842 memset(fl6, 0, sizeof(*fl6));841 memset(fl6, 0, sizeof(*fl6));
@@ -862,7 +861,6 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, · 19 unmodified lines
862 dst_cache = &geneve->dst_cache;861 dst_cache = &geneve->dst_cache;
863 }862 }
864 863
865 use_cache = use_cache && !skb->mark;
866 if (use_cache) {864 if (use_cache) {
867 dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);865 dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);
868 if (dst)866 if (dst)
@@ -940,7 +938,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 71 unmodified lines
940 u8 vni[3];938 u8 vni[3];
941 939
942 tunnel_id_to_vni(key->tun_id, vni);940 tunnel_id_to_vni(key->tun_id, vni);
943 if (key->tun_flags & TUNNEL_GENEVE_OPT)941 if (info->options_len)
944 opts = ip_tunnel_info_opts(info);942 opts = ip_tunnel_info_opts(info);
945 943
946 if (key->tun_flags & TUNNEL_CSUM)944 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, · 80 unmodified lines
1027 u8 vni[3];1025 u8 vni[3];
1028 1026
1029 tunnel_id_to_vni(key->tun_id, vni);1027 tunnel_id_to_vni(key->tun_id, vni);
1030 if (key->tun_flags & TUNNEL_GENEVE_OPT)1028 if (info->options_len)
1031 opts = ip_tunnel_info_opts(info);1029 opts = ip_tunnel_info_opts(info);
1032 1030
1033 if (key->tun_flags & TUNNEL_CSUM)1031 if (key->tun_flags & TUNNEL_CSUM)
drivers/net/vxlan.c+21−17
@@ -1756,17 +1756,15 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, · 1755 unmodified lines
1756 struct sk_buff *skb, int oif, u8 tos,1756 struct sk_buff *skb, int oif, u8 tos,
1757 __be32 daddr, __be32 *saddr,1757 __be32 daddr, __be32 *saddr,
1758 struct dst_cache *dst_cache,1758 struct dst_cache *dst_cache,
1759 struct ip_tunnel_info *info)1759 const struct ip_tunnel_info *info)
1760{1760{
1761 bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
1761 struct rtable *rt = NULL;1762 struct rtable *rt = NULL;
1762 bool use_cache = false;
1763 struct flowi4 fl4;1763 struct flowi4 fl4;
1764 1764
1765 /* when the ip_tunnel_info is availble, the tos used for lookup is1765 if (tos && !info)
1766 * packet independent, so we can use the cache1766 use_cache = false;
1767 */1767 if (use_cache) {
1768 if (!skb->mark && (!tos || info)) {
1769 use_cache = true;
1770 rt = dst_cache_get_ip4(dst_cache, saddr);1768 rt = dst_cache_get_ip4(dst_cache, saddr);
1771 if (rt)1769 if (rt)
1772 return rt;1770 return rt;
@@ -1791,16 +1789,20 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, · 18 unmodified lines
1791 1789
1792#if IS_ENABLED(CONFIG_IPV6)1790#if IS_ENABLED(CONFIG_IPV6)
1793static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,1791static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
1794 struct sk_buff *skb, int oif,1792 struct sk_buff *skb, int oif, u8 tos,
1795 const struct in6_addr *daddr,1793 const struct in6_addr *daddr,
1796 struct in6_addr *saddr,1794 struct in6_addr *saddr,
1797 struct dst_cache *dst_cache)1795 struct dst_cache *dst_cache,
1796 const struct ip_tunnel_info *info)
1798{1797{
1798 bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
1799 struct dst_entry *ndst;1799 struct dst_entry *ndst;
1800 struct flowi6 fl6;1800 struct flowi6 fl6;
1801 int err;1801 int err;
1802 1802
1803 if (!skb->mark) {1803 if (tos && !info)
1804 use_cache = false;
1805 if (use_cache) {
1804 ndst = dst_cache_get_ip6(dst_cache, saddr);1806 ndst = dst_cache_get_ip6(dst_cache, saddr);
1805 if (ndst)1807 if (ndst)
1806 return ndst;1808 return ndst;
@@ -1808,6 +1810,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, · 1 unmodified line
1808 1810
1809 memset(&fl6, 0, sizeof(fl6));1811 memset(&fl6, 0, sizeof(fl6));
1810 fl6.flowi6_oif = oif;1812 fl6.flowi6_oif = oif;
1813 fl6.flowi6_tos = RT_TOS(tos);
1811 fl6.daddr = *daddr;1814 fl6.daddr = *daddr;
1812 fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;1815 fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
1813 fl6.flowi6_mark = skb->mark;1816 fl6.flowi6_mark = skb->mark;
@@ -1820,7 +1823,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, · 6 unmodified lines
1820 return ERR_PTR(err);1823 return ERR_PTR(err);
1821 1824
1822 *saddr = fl6.saddr;1825 *saddr = fl6.saddr;
1823 if (!skb->mark)1826 if (use_cache)
1824 dst_cache_set_ip6(dst_cache, ndst, saddr);1827 dst_cache_set_ip6(dst_cache, ndst, saddr);
1825 return ndst;1828 return ndst;
1826}1829}
@@ -2016,9 +2019,9 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 189 unmodified lines
2016 sk = vxlan->vn6_sock->sock->sk;2019 sk = vxlan->vn6_sock->sock->sk;
2017 2020
2018 ndst = vxlan6_get_route(vxlan, skb,2021 ndst = vxlan6_get_route(vxlan, skb,
2019 rdst ? rdst->remote_ifindex : 0,2022 rdst ? rdst->remote_ifindex : 0, tos,
2020 &dst->sin6.sin6_addr, &saddr,2023 &dst->sin6.sin6_addr, &saddr,
2021 dst_cache);2024 dst_cache, info);
2022 if (IS_ERR(ndst)) {2025 if (IS_ERR(ndst)) {
2023 netdev_dbg(dev, "no route to %pI6\n",2026 netdev_dbg(dev, "no route to %pI6\n",
2024 &dst->sin6.sin6_addr);2027 &dst->sin6.sin6_addr);
@@ -2053,6 +2056,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 28 unmodified lines
2053 if (!info)2056 if (!info)
2054 udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);2057 udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
2055 2058
2059 tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
2056 ttl = ttl ? : ip6_dst_hoplimit(ndst);2060 ttl = ttl ? : ip6_dst_hoplimit(ndst);
2057 skb_scrub_packet(skb, xnet);2061 skb_scrub_packet(skb, xnet);
2058 err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),2062 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, · 3 unmodified lines
2062 return;2066 return;
2063 }2067 }
2064 udp_tunnel6_xmit_skb(ndst, sk, skb, dev,2068 udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
2065 &saddr, &dst->sin6.sin6_addr,2069 &saddr, &dst->sin6.sin6_addr, tos, ttl,
2066 0, ttl, src_port, dst_port, !udp_sum);2070 src_port, dst_port, !udp_sum);
2067#endif2071#endif
2068 }2072 }
2069 2073
@@ -2385,9 +2389,9 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) · 315 unmodified lines
2385 2389
2386 if (!vxlan->vn6_sock)2390 if (!vxlan->vn6_sock)
2387 return -EINVAL;2391 return -EINVAL;
2388 ndst = vxlan6_get_route(vxlan, skb, 0,2392 ndst = vxlan6_get_route(vxlan, skb, 0, info->key.tos,
2389 &info->key.u.ipv6.dst,2393 &info->key.u.ipv6.dst,
2390 &info->key.u.ipv6.src, NULL);2394 &info->key.u.ipv6.src, NULL, info);
2391 if (IS_ERR(ndst))2395 if (IS_ERR(ndst))
2392 return PTR_ERR(ndst);2396 return PTR_ERR(ndst);
2393 dst_release(ndst);2397 dst_release(ndst);
include/net/checksum.h+5−0
@@ -120,6 +120,11 @@ static inline __wsum csum_partial_ext(const void *buff, int len, __wsum sum) · 119 unmodified lines
120 120
121#define CSUM_MANGLED_0 ((__force __sum16)0xffff)121#define CSUM_MANGLED_0 ((__force __sum16)0xffff)
122 122
123static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff)
124{
125 *sum = csum_fold(csum_add(diff, ~csum_unfold(*sum)));
126}
127
123static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)128static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
124{129{
125 __wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from);130 __wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from);
include/net/ip_tunnels.h+15−0
@@ -140,6 +140,7 @@ struct ip_tunnel { · 139 unmodified lines
140#define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400)140#define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400)
141#define TUNNEL_GENEVE_OPT __cpu_to_be16(0x0800)141#define TUNNEL_GENEVE_OPT __cpu_to_be16(0x0800)
142#define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000)142#define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000)
143#define TUNNEL_NOCACHE __cpu_to_be16(0x2000)
143 144
144#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)145#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)
145 146
@@ -206,6 +207,20 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key, · 60 unmodified lines
206 0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);207 0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
207}208}
208 209
210static inline bool
211ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
212 const struct ip_tunnel_info *info)
213{
214 if (skb->mark)
215 return false;
216 if (!info)
217 return true;
218 if (info->key.tun_flags & TUNNEL_NOCACHE)
219 return false;
220
221 return true;
222}
223
209static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info224static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
210 *tun_info)225 *tun_info)
211{226{
include/uapi/linux/bpf.h+13−0
@@ -298,6 +298,17 @@ enum bpf_func_id { · 297 unmodified lines
298 * Return: csum result298 * Return: csum result
299 */299 */
300 BPF_FUNC_csum_diff,300 BPF_FUNC_csum_diff,
301
302 /**
303 * bpf_skb_[gs]et_tunnel_opt(skb, opt, size)
304 * retrieve or populate tunnel options metadata
305 * @skb: pointer to skb
306 * @opt: pointer to raw tunnel option data
307 * @size: size of @opt
308 * Return: 0 on success for set, option size for get
309 */
310 BPF_FUNC_skb_get_tunnel_opt,
311 BPF_FUNC_skb_set_tunnel_opt,
301 __BPF_FUNC_MAX_ID,312 __BPF_FUNC_MAX_ID,
302};313};
303 314
@@ -305,6 +316,7 @@ enum bpf_func_id { · 1 unmodified line
305 316
306/* BPF_FUNC_skb_store_bytes flags. */317/* BPF_FUNC_skb_store_bytes flags. */
307#define BPF_F_RECOMPUTE_CSUM (1ULL << 0)318#define BPF_F_RECOMPUTE_CSUM (1ULL << 0)
319#define BPF_F_INVALIDATE_HASH (1ULL << 1)
308 320
309/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.321/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.
310 * First 4 bits are for passing the header field size.322 * First 4 bits are for passing the header field size.
@@ -329,6 +341,7 @@ enum bpf_func_id { · 18 unmodified lines
329 341
330/* BPF_FUNC_skb_set_tunnel_key flags. */342/* BPF_FUNC_skb_set_tunnel_key flags. */
331#define BPF_F_ZERO_CSUM_TX (1ULL << 1)343#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
344#define BPF_F_DONT_FRAGMENT (1ULL << 2)
332 345
333/* user accessible mirror of in-kernel sk_buff.346/* user accessible mirror of in-kernel sk_buff.
334 * new fields can only be added to the end of this structure347 * new fields can only be added to the end of this structure
net/core/filter.c+101−18
@@ -1353,7 +1353,7 @@ static u64 bpf_skb_store_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 flags) · 1352 unmodified lines
1353 unsigned int len = (unsigned int) r4;1353 unsigned int len = (unsigned int) r4;
1354 void *ptr;1354 void *ptr;
1355 1355
1356 if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM)))1356 if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM | BPF_F_INVALIDATE_HASH)))
1357 return -EINVAL;1357 return -EINVAL;
1358 1358
1359 /* bpf verifier guarantees that:1359 /* bpf verifier guarantees that:
@@ -1384,11 +1384,13 @@ static u64 bpf_skb_store_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 flags) · 24 unmodified lines
1384 1384
1385 if (flags & BPF_F_RECOMPUTE_CSUM)1385 if (flags & BPF_F_RECOMPUTE_CSUM)
1386 skb_postpush_rcsum(skb, ptr, len);1386 skb_postpush_rcsum(skb, ptr, len);
1387 if (flags & BPF_F_INVALIDATE_HASH)
1388 skb_clear_hash(skb);
1387 1389
1388 return 0;1390 return 0;
1389}1391}
1390 1392
1391const struct bpf_func_proto bpf_skb_store_bytes_proto = {1393static const struct bpf_func_proto bpf_skb_store_bytes_proto = {
1392 .func = bpf_skb_store_bytes,1394 .func = bpf_skb_store_bytes,
1393 .gpl_only = false,1395 .gpl_only = false,
1394 .ret_type = RET_INTEGER,1396 .ret_type = RET_INTEGER,
@@ -1419,7 +1421,7 @@ static u64 bpf_skb_load_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) · 24 unmodified lines
1419 return 0;1421 return 0;
1420}1422}
1421 1423
1422const struct bpf_func_proto bpf_skb_load_bytes_proto = {1424static const struct bpf_func_proto bpf_skb_load_bytes_proto = {
1423 .func = bpf_skb_load_bytes,1425 .func = bpf_skb_load_bytes,
1424 .gpl_only = false,1426 .gpl_only = false,
1425 .ret_type = RET_INTEGER,1427 .ret_type = RET_INTEGER,
@@ -1447,6 +1449,12 @@ static u64 bpf_l3_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) · 21 unmodified lines
1447 return -EFAULT;1449 return -EFAULT;
1448 1450
1449 switch (flags & BPF_F_HDR_FIELD_MASK) {1451 switch (flags & BPF_F_HDR_FIELD_MASK) {
1452 case 0:
1453 if (unlikely(from != 0))
1454 return -EINVAL;
1455
1456 csum_replace_by_diff(ptr, to);
1457 break;
1450 case 2:1458 case 2:
1451 csum_replace2(ptr, from, to);1459 csum_replace2(ptr, from, to);
1452 break;1460 break;
@@ -1464,7 +1472,7 @@ static u64 bpf_l3_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) · 11 unmodified lines
1464 return 0;1472 return 0;
1465}1473}
1466 1474
1467const struct bpf_func_proto bpf_l3_csum_replace_proto = {1475static const struct bpf_func_proto bpf_l3_csum_replace_proto = {
1468 .func = bpf_l3_csum_replace,1476 .func = bpf_l3_csum_replace,
1469 .gpl_only = false,1477 .gpl_only = false,
1470 .ret_type = RET_INTEGER,1478 .ret_type = RET_INTEGER,
@@ -1523,7 +1531,7 @@ static u64 bpf_l4_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) · 52 unmodified lines
1523 return 0;1531 return 0;
1524}1532}
1525 1533
1526const struct bpf_func_proto bpf_l4_csum_replace_proto = {1534static const struct bpf_func_proto bpf_l4_csum_replace_proto = {
1527 .func = bpf_l4_csum_replace,1535 .func = bpf_l4_csum_replace,
1528 .gpl_only = false,1536 .gpl_only = false,
1529 .ret_type = RET_INTEGER,1537 .ret_type = RET_INTEGER,
@@ -1562,7 +1570,7 @@ static u64 bpf_csum_diff(u64 r1, u64 from_size, u64 r3, u64 to_size, u64 seed) · 32 unmodified lines
1562 return csum_partial(sp->diff, diff_size, seed);1570 return csum_partial(sp->diff, diff_size, seed);
1563}1571}
1564 1572
1565const struct bpf_func_proto bpf_csum_diff_proto = {1573static const struct bpf_func_proto bpf_csum_diff_proto = {
1566 .func = bpf_csum_diff,1574 .func = bpf_csum_diff,
1567 .gpl_only = false,1575 .gpl_only = false,
1568 .ret_type = RET_INTEGER,1576 .ret_type = RET_INTEGER,
@@ -1600,7 +1608,7 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5) · 31 unmodified lines
1600 return dev_queue_xmit(skb2);1608 return dev_queue_xmit(skb2);
1601}1609}
1602 1610
1603const struct bpf_func_proto bpf_clone_redirect_proto = {1611static const struct bpf_func_proto bpf_clone_redirect_proto = {
1604 .func = bpf_clone_redirect,1612 .func = bpf_clone_redirect,
1605 .gpl_only = false,1613 .gpl_only = false,
1606 .ret_type = RET_INTEGER,1614 .ret_type = RET_INTEGER,
@@ -1652,7 +1660,7 @@ int skb_do_redirect(struct sk_buff *skb) · 45 unmodified lines
1652 return dev_queue_xmit(skb);1660 return dev_queue_xmit(skb);
1653}1661}
1654 1662
1655const struct bpf_func_proto bpf_redirect_proto = {1663static const struct bpf_func_proto bpf_redirect_proto = {
1656 .func = bpf_redirect,1664 .func = bpf_redirect,
1657 .gpl_only = false,1665 .gpl_only = false,
1658 .ret_type = RET_INTEGER,1666 .ret_type = RET_INTEGER,
@@ -1791,7 +1799,7 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) · 132 unmodified lines
1791 return 0;1799 return 0;
1792}1800}
1793 1801
1794const struct bpf_func_proto bpf_skb_get_tunnel_key_proto = {1802static const struct bpf_func_proto bpf_skb_get_tunnel_key_proto = {
1795 .func = bpf_skb_get_tunnel_key,1803 .func = bpf_skb_get_tunnel_key,
1796 .gpl_only = false,1804 .gpl_only = false,
1797 .ret_type = RET_INTEGER,1805 .ret_type = RET_INTEGER,
@@ -1801,6 +1809,32 @@ const struct bpf_func_proto bpf_skb_get_tunnel_key_proto = { · 3 unmodified lines
1801 .arg4_type = ARG_ANYTHING,1809 .arg4_type = ARG_ANYTHING,
1802};1810};
1803 1811
1812static u64 bpf_skb_get_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5)
1813{
1814 struct sk_buff *skb = (struct sk_buff *) (long) r1;
1815 u8 *to = (u8 *) (long) r2;
1816 const struct ip_tunnel_info *info = skb_tunnel_info(skb);
1817
1818 if (unlikely(!info ||
1819 !(info->key.tun_flags & TUNNEL_OPTIONS_PRESENT)))
1820 return -ENOENT;
1821 if (unlikely(size < info->options_len))
1822 return -ENOMEM;
1823
1824 ip_tunnel_info_opts_get(to, info);
1825
1826 return info->options_len;
1827}
1828
1829static const struct bpf_func_proto bpf_skb_get_tunnel_opt_proto = {
1830 .func = bpf_skb_get_tunnel_opt,
1831 .gpl_only = false,
1832 .ret_type = RET_INTEGER,
1833 .arg1_type = ARG_PTR_TO_CTX,
1834 .arg2_type = ARG_PTR_TO_STACK,
1835 .arg3_type = ARG_CONST_STACK_SIZE,
1836};
1837
1804static struct metadata_dst __percpu *md_dst;1838static struct metadata_dst __percpu *md_dst;
1805 1839
1806static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)1840static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
@@ -1811,7 +1845,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) · 4 unmodified lines
1811 u8 compat[sizeof(struct bpf_tunnel_key)];1845 u8 compat[sizeof(struct bpf_tunnel_key)];
1812 struct ip_tunnel_info *info;1846 struct ip_tunnel_info *info;
1813 1847
1814 if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX)))1848 if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
1849 BPF_F_DONT_FRAGMENT)))
1815 return -EINVAL;1850 return -EINVAL;
1816 if (unlikely(size != sizeof(struct bpf_tunnel_key))) {1851 if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
1817 switch (size) {1852 switch (size) {
@@ -1835,7 +1870,10 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) · 17 unmodified lines
1835 info = &md->u.tun_info;1870 info = &md->u.tun_info;
1836 info->mode = IP_TUNNEL_INFO_TX;1871 info->mode = IP_TUNNEL_INFO_TX;
1837 1872
1838 info->key.tun_flags = TUNNEL_KEY | TUNNEL_CSUM;1873 info->key.tun_flags = TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_NOCACHE;
1874 if (flags & BPF_F_DONT_FRAGMENT)
1875 info->key.tun_flags |= TUNNEL_DONT_FRAGMENT;
1876
1839 info->key.tun_id = cpu_to_be64(from->tunnel_id);1877 info->key.tun_id = cpu_to_be64(from->tunnel_id);
1840 info->key.tos = from->tunnel_tos;1878 info->key.tos = from->tunnel_tos;
1841 info->key.ttl = from->tunnel_ttl;1879 info->key.ttl = from->tunnel_ttl;
@@ -1853,7 +1891,7 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) · 11 unmodified lines
1853 return 0;1891 return 0;
1854}1892}
1855 1893
1856const struct bpf_func_proto bpf_skb_set_tunnel_key_proto = {1894static const struct bpf_func_proto bpf_skb_set_tunnel_key_proto = {
1857 .func = bpf_skb_set_tunnel_key,1895 .func = bpf_skb_set_tunnel_key,
1858 .gpl_only = false,1896 .gpl_only = false,
1859 .ret_type = RET_INTEGER,1897 .ret_type = RET_INTEGER,
@@ -1863,17 +1901,58 @@ const struct bpf_func_proto bpf_skb_set_tunnel_key_proto = { · 3 unmodified lines
1863 .arg4_type = ARG_ANYTHING,1901 .arg4_type = ARG_ANYTHING,
1864};1902};
1865 1903
1866static const struct bpf_func_proto *bpf_get_skb_set_tunnel_key_proto(void)1904#define BPF_TUNLEN_MAX 255
1905
1906static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5)
1907{
1908 struct sk_buff *skb = (struct sk_buff *) (long) r1;
1909 u8 *from = (u8 *) (long) r2;
1910 struct ip_tunnel_info *info = skb_tunnel_info(skb);
1911 const struct metadata_dst *md = this_cpu_ptr(md_dst);
1912
1913 if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1))))
1914 return -EINVAL;
1915 if (unlikely(size > BPF_TUNLEN_MAX))
1916 return -ENOMEM;
1917
1918 ip_tunnel_info_opts_set(info, from, size);
1919
1920 return 0;
1921}
1922
1923static const struct bpf_func_proto bpf_skb_set_tunnel_opt_proto = {
1924 .func = bpf_skb_set_tunnel_opt,
1925 .gpl_only = false,
1926 .ret_type = RET_INTEGER,
1927 .arg1_type = ARG_PTR_TO_CTX,
1928 .arg2_type = ARG_PTR_TO_STACK,
1929 .arg3_type = ARG_CONST_STACK_SIZE,
1930};
1931
1932static const struct bpf_func_proto *
1933bpf_get_skb_set_tunnel_proto(enum bpf_func_id which)
1867{1934{
1868 if (!md_dst) {1935 if (!md_dst) {
1869 /* race is not possible, since it's called from1936 BUILD_BUG_ON(FIELD_SIZEOF(struct ip_tunnel_info,
1870 * verifier that is holding verifier mutex1937 options_len) != 1);
1938
1939 /* Race is not possible, since it's called from verifier
1940 * that is holding verifier mutex.
1871 */1941 */
1872 md_dst = metadata_dst_alloc_percpu(0, GFP_KERNEL);1942 md_dst = metadata_dst_alloc_percpu(BPF_TUNLEN_MAX,
1943 GFP_KERNEL);
1873 if (!md_dst)1944 if (!md_dst)
1874 return NULL;1945 return NULL;
1875 }1946 }
1876 return &bpf_skb_set_tunnel_key_proto;1947
1948 switch (which) {
1949 case BPF_FUNC_skb_set_tunnel_key:
1950 return &bpf_skb_set_tunnel_key_proto;
1951 case BPF_FUNC_skb_set_tunnel_opt:
1952 return &bpf_skb_set_tunnel_opt_proto;
1953 default:
1954 return NULL;
1955 }
1877}1956}
1878 1957
1879static const struct bpf_func_proto *1958static const struct bpf_func_proto *
@@ -1927,7 +2006,11 @@ tc_cls_act_func_proto(enum bpf_func_id func_id) · 47 unmodified lines
1927 case BPF_FUNC_skb_get_tunnel_key:2006 case BPF_FUNC_skb_get_tunnel_key:
1928 return &bpf_skb_get_tunnel_key_proto;2007 return &bpf_skb_get_tunnel_key_proto;
1929 case BPF_FUNC_skb_set_tunnel_key:2008 case BPF_FUNC_skb_set_tunnel_key:
1930 return bpf_get_skb_set_tunnel_key_proto();2009 return bpf_get_skb_set_tunnel_proto(func_id);
2010 case BPF_FUNC_skb_get_tunnel_opt:
2011 return &bpf_skb_get_tunnel_opt_proto;
2012 case BPF_FUNC_skb_set_tunnel_opt:
2013 return bpf_get_skb_set_tunnel_proto(func_id);
1931 case BPF_FUNC_redirect:2014 case BPF_FUNC_redirect:
1932 return &bpf_redirect_proto;2015 return &bpf_redirect_proto;
1933 case BPF_FUNC_get_route_realm:2016 case BPF_FUNC_get_route_realm:
net/ipv4/ip_gre.c+6−4
@@ -527,11 +527,12 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) · 526 unmodified lines
527{527{
528 struct ip_tunnel_info *tun_info;528 struct ip_tunnel_info *tun_info;
529 const struct ip_tunnel_key *key;529 const struct ip_tunnel_key *key;
530 struct rtable *rt = NULL;
530 struct flowi4 fl;531 struct flowi4 fl;
531 struct rtable *rt;
532 int min_headroom;532 int min_headroom;
533 int tunnel_hlen;533 int tunnel_hlen;
534 __be16 df, flags;534 __be16 df, flags;
535 bool use_cache;
535 int err;536 int err;
536 537
537 tun_info = skb_tunnel_info(skb);538 tun_info = skb_tunnel_info(skb);
@@ -540,13 +541,14 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) · 2 unmodified lines
540 goto err_free_skb;541 goto err_free_skb;
541 542
542 key = &tun_info->key;543 key = &tun_info->key;
543 rt = !skb->mark ? dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr) :544 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
544 NULL;545 if (use_cache)
546 rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr);
545 if (!rt) {547 if (!rt) {
546 rt = gre_get_rt(skb, dev, &fl, key);548 rt = gre_get_rt(skb, dev, &fl, key);
547 if (IS_ERR(rt))549 if (IS_ERR(rt))
548 goto err_free_skb;550 goto err_free_skb;
549 if (!skb->mark)551 if (use_cache)
550 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,552 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
551 fl.saddr);553 fl.saddr);
552 }554 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t