diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 10 | ||||
-rw-r--r-- | net/core/filter.c | 109 |
2 files changed, 50 insertions, 69 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 4ce07dc25573..dd6ce598de89 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -6045,8 +6045,7 @@ void *netdev_lower_dev_get_private(struct net_device *dev, | |||
6045 | EXPORT_SYMBOL(netdev_lower_dev_get_private); | 6045 | EXPORT_SYMBOL(netdev_lower_dev_get_private); |
6046 | 6046 | ||
6047 | 6047 | ||
6048 | int dev_get_nest_level(struct net_device *dev, | 6048 | int dev_get_nest_level(struct net_device *dev) |
6049 | bool (*type_check)(const struct net_device *dev)) | ||
6050 | { | 6049 | { |
6051 | struct net_device *lower = NULL; | 6050 | struct net_device *lower = NULL; |
6052 | struct list_head *iter; | 6051 | struct list_head *iter; |
@@ -6056,15 +6055,12 @@ int dev_get_nest_level(struct net_device *dev, | |||
6056 | ASSERT_RTNL(); | 6055 | ASSERT_RTNL(); |
6057 | 6056 | ||
6058 | netdev_for_each_lower_dev(dev, lower, iter) { | 6057 | netdev_for_each_lower_dev(dev, lower, iter) { |
6059 | nest = dev_get_nest_level(lower, type_check); | 6058 | nest = dev_get_nest_level(lower); |
6060 | if (max_nest < nest) | 6059 | if (max_nest < nest) |
6061 | max_nest = nest; | 6060 | max_nest = nest; |
6062 | } | 6061 | } |
6063 | 6062 | ||
6064 | if (type_check(dev)) | 6063 | return max_nest + 1; |
6065 | max_nest++; | ||
6066 | |||
6067 | return max_nest; | ||
6068 | } | 6064 | } |
6069 | EXPORT_SYMBOL(dev_get_nest_level); | 6065 | EXPORT_SYMBOL(dev_get_nest_level); |
6070 | 6066 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index 5708999f8a79..cb06aceb512a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -1355,56 +1355,47 @@ static inline int bpf_try_make_writable(struct sk_buff *skb, | |||
1355 | { | 1355 | { |
1356 | int err; | 1356 | int err; |
1357 | 1357 | ||
1358 | if (!skb_cloned(skb)) | 1358 | err = skb_ensure_writable(skb, write_len); |
1359 | return 0; | 1359 | bpf_compute_data_end(skb); |
1360 | if (skb_clone_writable(skb, write_len)) | 1360 | |
1361 | return 0; | ||
1362 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | ||
1363 | if (!err) | ||
1364 | bpf_compute_data_end(skb); | ||
1365 | return err; | 1361 | return err; |
1366 | } | 1362 | } |
1367 | 1363 | ||
1364 | static inline void bpf_push_mac_rcsum(struct sk_buff *skb) | ||
1365 | { | ||
1366 | if (skb_at_tc_ingress(skb)) | ||
1367 | skb_postpush_rcsum(skb, skb_mac_header(skb), skb->mac_len); | ||
1368 | } | ||
1369 | |||
1370 | static inline void bpf_pull_mac_rcsum(struct sk_buff *skb) | ||
1371 | { | ||
1372 | if (skb_at_tc_ingress(skb)) | ||
1373 | skb_postpull_rcsum(skb, skb_mac_header(skb), skb->mac_len); | ||
1374 | } | ||
1375 | |||
1368 | static u64 bpf_skb_store_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 flags) | 1376 | static u64 bpf_skb_store_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 flags) |
1369 | { | 1377 | { |
1370 | struct bpf_scratchpad *sp = this_cpu_ptr(&bpf_sp); | ||
1371 | struct sk_buff *skb = (struct sk_buff *) (long) r1; | 1378 | struct sk_buff *skb = (struct sk_buff *) (long) r1; |
1372 | int offset = (int) r2; | 1379 | unsigned int offset = (unsigned int) r2; |
1373 | void *from = (void *) (long) r3; | 1380 | void *from = (void *) (long) r3; |
1374 | unsigned int len = (unsigned int) r4; | 1381 | unsigned int len = (unsigned int) r4; |
1375 | void *ptr; | 1382 | void *ptr; |
1376 | 1383 | ||
1377 | if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM | BPF_F_INVALIDATE_HASH))) | 1384 | if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM | BPF_F_INVALIDATE_HASH))) |
1378 | return -EINVAL; | 1385 | return -EINVAL; |
1379 | 1386 | if (unlikely(offset > 0xffff)) | |
1380 | /* bpf verifier guarantees that: | ||
1381 | * 'from' pointer points to bpf program stack | ||
1382 | * 'len' bytes of it were initialized | ||
1383 | * 'len' > 0 | ||
1384 | * 'skb' is a valid pointer to 'struct sk_buff' | ||
1385 | * | ||
1386 | * so check for invalid 'offset' and too large 'len' | ||
1387 | */ | ||
1388 | if (unlikely((u32) offset > 0xffff || len > sizeof(sp->buff))) | ||
1389 | return -EFAULT; | 1387 | return -EFAULT; |
1390 | if (unlikely(bpf_try_make_writable(skb, offset + len))) | 1388 | if (unlikely(bpf_try_make_writable(skb, offset + len))) |
1391 | return -EFAULT; | 1389 | return -EFAULT; |
1392 | 1390 | ||
1393 | ptr = skb_header_pointer(skb, offset, len, sp->buff); | 1391 | ptr = skb->data + offset; |
1394 | if (unlikely(!ptr)) | ||
1395 | return -EFAULT; | ||
1396 | |||
1397 | if (flags & BPF_F_RECOMPUTE_CSUM) | 1392 | if (flags & BPF_F_RECOMPUTE_CSUM) |
1398 | skb_postpull_rcsum(skb, ptr, len); | 1393 | __skb_postpull_rcsum(skb, ptr, len, offset); |
1399 | 1394 | ||
1400 | memcpy(ptr, from, len); | 1395 | memcpy(ptr, from, len); |
1401 | 1396 | ||
1402 | if (ptr == sp->buff) | ||
1403 | /* skb_store_bits cannot return -EFAULT here */ | ||
1404 | skb_store_bits(skb, offset, ptr, len); | ||
1405 | |||
1406 | if (flags & BPF_F_RECOMPUTE_CSUM) | 1397 | if (flags & BPF_F_RECOMPUTE_CSUM) |
1407 | skb_postpush_rcsum(skb, ptr, len); | 1398 | __skb_postpush_rcsum(skb, ptr, len, offset); |
1408 | if (flags & BPF_F_INVALIDATE_HASH) | 1399 | if (flags & BPF_F_INVALIDATE_HASH) |
1409 | skb_clear_hash(skb); | 1400 | skb_clear_hash(skb); |
1410 | 1401 | ||
@@ -1425,12 +1416,12 @@ static const struct bpf_func_proto bpf_skb_store_bytes_proto = { | |||
1425 | static u64 bpf_skb_load_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | 1416 | static u64 bpf_skb_load_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) |
1426 | { | 1417 | { |
1427 | const struct sk_buff *skb = (const struct sk_buff *)(unsigned long) r1; | 1418 | const struct sk_buff *skb = (const struct sk_buff *)(unsigned long) r1; |
1428 | int offset = (int) r2; | 1419 | unsigned int offset = (unsigned int) r2; |
1429 | void *to = (void *)(unsigned long) r3; | 1420 | void *to = (void *)(unsigned long) r3; |
1430 | unsigned int len = (unsigned int) r4; | 1421 | unsigned int len = (unsigned int) r4; |
1431 | void *ptr; | 1422 | void *ptr; |
1432 | 1423 | ||
1433 | if (unlikely((u32) offset > 0xffff)) | 1424 | if (unlikely(offset > 0xffff)) |
1434 | goto err_clear; | 1425 | goto err_clear; |
1435 | 1426 | ||
1436 | ptr = skb_header_pointer(skb, offset, len, to); | 1427 | ptr = skb_header_pointer(skb, offset, len, to); |
@@ -1458,20 +1449,17 @@ static const struct bpf_func_proto bpf_skb_load_bytes_proto = { | |||
1458 | static u64 bpf_l3_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) | 1449 | static u64 bpf_l3_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) |
1459 | { | 1450 | { |
1460 | struct sk_buff *skb = (struct sk_buff *) (long) r1; | 1451 | struct sk_buff *skb = (struct sk_buff *) (long) r1; |
1461 | int offset = (int) r2; | 1452 | unsigned int offset = (unsigned int) r2; |
1462 | __sum16 sum, *ptr; | 1453 | __sum16 *ptr; |
1463 | 1454 | ||
1464 | if (unlikely(flags & ~(BPF_F_HDR_FIELD_MASK))) | 1455 | if (unlikely(flags & ~(BPF_F_HDR_FIELD_MASK))) |
1465 | return -EINVAL; | 1456 | return -EINVAL; |
1466 | if (unlikely((u32) offset > 0xffff)) | 1457 | if (unlikely(offset > 0xffff || offset & 1)) |
1467 | return -EFAULT; | 1458 | return -EFAULT; |
1468 | if (unlikely(bpf_try_make_writable(skb, offset + sizeof(sum)))) | 1459 | if (unlikely(bpf_try_make_writable(skb, offset + sizeof(*ptr)))) |
1469 | return -EFAULT; | ||
1470 | |||
1471 | ptr = skb_header_pointer(skb, offset, sizeof(sum), &sum); | ||
1472 | if (unlikely(!ptr)) | ||
1473 | return -EFAULT; | 1460 | return -EFAULT; |
1474 | 1461 | ||
1462 | ptr = (__sum16 *)(skb->data + offset); | ||
1475 | switch (flags & BPF_F_HDR_FIELD_MASK) { | 1463 | switch (flags & BPF_F_HDR_FIELD_MASK) { |
1476 | case 0: | 1464 | case 0: |
1477 | if (unlikely(from != 0)) | 1465 | if (unlikely(from != 0)) |
@@ -1489,10 +1477,6 @@ static u64 bpf_l3_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) | |||
1489 | return -EINVAL; | 1477 | return -EINVAL; |
1490 | } | 1478 | } |
1491 | 1479 | ||
1492 | if (ptr == &sum) | ||
1493 | /* skb_store_bits guaranteed to not return -EFAULT here */ | ||
1494 | skb_store_bits(skb, offset, ptr, sizeof(sum)); | ||
1495 | |||
1496 | return 0; | 1480 | return 0; |
1497 | } | 1481 | } |
1498 | 1482 | ||
@@ -1512,20 +1496,18 @@ static u64 bpf_l4_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) | |||
1512 | struct sk_buff *skb = (struct sk_buff *) (long) r1; | 1496 | struct sk_buff *skb = (struct sk_buff *) (long) r1; |
1513 | bool is_pseudo = flags & BPF_F_PSEUDO_HDR; | 1497 | bool is_pseudo = flags & BPF_F_PSEUDO_HDR; |
1514 | bool is_mmzero = flags & BPF_F_MARK_MANGLED_0; | 1498 | bool is_mmzero = flags & BPF_F_MARK_MANGLED_0; |
1515 | int offset = (int) r2; | 1499 | unsigned int offset = (unsigned int) r2; |
1516 | __sum16 sum, *ptr; | 1500 | __sum16 *ptr; |
1517 | 1501 | ||
1518 | if (unlikely(flags & ~(BPF_F_MARK_MANGLED_0 | BPF_F_PSEUDO_HDR | | 1502 | if (unlikely(flags & ~(BPF_F_MARK_MANGLED_0 | BPF_F_PSEUDO_HDR | |
1519 | BPF_F_HDR_FIELD_MASK))) | 1503 | BPF_F_HDR_FIELD_MASK))) |
1520 | return -EINVAL; | 1504 | return -EINVAL; |
1521 | if (unlikely((u32) offset > 0xffff)) | 1505 | if (unlikely(offset > 0xffff || offset & 1)) |
1522 | return -EFAULT; | 1506 | return -EFAULT; |
1523 | if (unlikely(bpf_try_make_writable(skb, offset + sizeof(sum)))) | 1507 | if (unlikely(bpf_try_make_writable(skb, offset + sizeof(*ptr)))) |
1524 | return -EFAULT; | 1508 | return -EFAULT; |
1525 | 1509 | ||
1526 | ptr = skb_header_pointer(skb, offset, sizeof(sum), &sum); | 1510 | ptr = (__sum16 *)(skb->data + offset); |
1527 | if (unlikely(!ptr)) | ||
1528 | return -EFAULT; | ||
1529 | if (is_mmzero && !*ptr) | 1511 | if (is_mmzero && !*ptr) |
1530 | return 0; | 1512 | return 0; |
1531 | 1513 | ||
@@ -1548,10 +1530,6 @@ static u64 bpf_l4_csum_replace(u64 r1, u64 r2, u64 from, u64 to, u64 flags) | |||
1548 | 1530 | ||
1549 | if (is_mmzero && !*ptr) | 1531 | if (is_mmzero && !*ptr) |
1550 | *ptr = CSUM_MANGLED_0; | 1532 | *ptr = CSUM_MANGLED_0; |
1551 | if (ptr == &sum) | ||
1552 | /* skb_store_bits guaranteed to not return -EFAULT here */ | ||
1553 | skb_store_bits(skb, offset, ptr, sizeof(sum)); | ||
1554 | |||
1555 | return 0; | 1533 | return 0; |
1556 | } | 1534 | } |
1557 | 1535 | ||
@@ -1607,9 +1585,6 @@ static const struct bpf_func_proto bpf_csum_diff_proto = { | |||
1607 | 1585 | ||
1608 | static inline int __bpf_rx_skb(struct net_device *dev, struct sk_buff *skb) | 1586 | static inline int __bpf_rx_skb(struct net_device *dev, struct sk_buff *skb) |
1609 | { | 1587 | { |
1610 | if (skb_at_tc_ingress(skb)) | ||
1611 | skb_postpush_rcsum(skb, skb_mac_header(skb), skb->mac_len); | ||
1612 | |||
1613 | return dev_forward_skb(dev, skb); | 1588 | return dev_forward_skb(dev, skb); |
1614 | } | 1589 | } |
1615 | 1590 | ||
@@ -1648,6 +1623,8 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5) | |||
1648 | if (unlikely(!skb)) | 1623 | if (unlikely(!skb)) |
1649 | return -ENOMEM; | 1624 | return -ENOMEM; |
1650 | 1625 | ||
1626 | bpf_push_mac_rcsum(skb); | ||
1627 | |||
1651 | return flags & BPF_F_INGRESS ? | 1628 | return flags & BPF_F_INGRESS ? |
1652 | __bpf_rx_skb(dev, skb) : __bpf_tx_skb(dev, skb); | 1629 | __bpf_rx_skb(dev, skb) : __bpf_tx_skb(dev, skb); |
1653 | } | 1630 | } |
@@ -1693,6 +1670,8 @@ int skb_do_redirect(struct sk_buff *skb) | |||
1693 | return -EINVAL; | 1670 | return -EINVAL; |
1694 | } | 1671 | } |
1695 | 1672 | ||
1673 | bpf_push_mac_rcsum(skb); | ||
1674 | |||
1696 | return ri->flags & BPF_F_INGRESS ? | 1675 | return ri->flags & BPF_F_INGRESS ? |
1697 | __bpf_rx_skb(dev, skb) : __bpf_tx_skb(dev, skb); | 1676 | __bpf_rx_skb(dev, skb) : __bpf_tx_skb(dev, skb); |
1698 | } | 1677 | } |
@@ -1756,7 +1735,10 @@ static u64 bpf_skb_vlan_push(u64 r1, u64 r2, u64 vlan_tci, u64 r4, u64 r5) | |||
1756 | vlan_proto != htons(ETH_P_8021AD))) | 1735 | vlan_proto != htons(ETH_P_8021AD))) |
1757 | vlan_proto = htons(ETH_P_8021Q); | 1736 | vlan_proto = htons(ETH_P_8021Q); |
1758 | 1737 | ||
1738 | bpf_push_mac_rcsum(skb); | ||
1759 | ret = skb_vlan_push(skb, vlan_proto, vlan_tci); | 1739 | ret = skb_vlan_push(skb, vlan_proto, vlan_tci); |
1740 | bpf_pull_mac_rcsum(skb); | ||
1741 | |||
1760 | bpf_compute_data_end(skb); | 1742 | bpf_compute_data_end(skb); |
1761 | return ret; | 1743 | return ret; |
1762 | } | 1744 | } |
@@ -1776,7 +1758,10 @@ static u64 bpf_skb_vlan_pop(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | |||
1776 | struct sk_buff *skb = (struct sk_buff *) (long) r1; | 1758 | struct sk_buff *skb = (struct sk_buff *) (long) r1; |
1777 | int ret; | 1759 | int ret; |
1778 | 1760 | ||
1761 | bpf_push_mac_rcsum(skb); | ||
1779 | ret = skb_vlan_pop(skb); | 1762 | ret = skb_vlan_pop(skb); |
1763 | bpf_pull_mac_rcsum(skb); | ||
1764 | |||
1780 | bpf_compute_data_end(skb); | 1765 | bpf_compute_data_end(skb); |
1781 | return ret; | 1766 | return ret; |
1782 | } | 1767 | } |
@@ -2298,7 +2283,7 @@ bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) | |||
2298 | } | 2283 | } |
2299 | 2284 | ||
2300 | #ifdef CONFIG_SOCK_CGROUP_DATA | 2285 | #ifdef CONFIG_SOCK_CGROUP_DATA |
2301 | static u64 bpf_skb_in_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | 2286 | static u64 bpf_skb_under_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) |
2302 | { | 2287 | { |
2303 | struct sk_buff *skb = (struct sk_buff *)(long)r1; | 2288 | struct sk_buff *skb = (struct sk_buff *)(long)r1; |
2304 | struct bpf_map *map = (struct bpf_map *)(long)r2; | 2289 | struct bpf_map *map = (struct bpf_map *)(long)r2; |
@@ -2321,8 +2306,8 @@ static u64 bpf_skb_in_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | |||
2321 | return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); | 2306 | return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); |
2322 | } | 2307 | } |
2323 | 2308 | ||
2324 | static const struct bpf_func_proto bpf_skb_in_cgroup_proto = { | 2309 | static const struct bpf_func_proto bpf_skb_under_cgroup_proto = { |
2325 | .func = bpf_skb_in_cgroup, | 2310 | .func = bpf_skb_under_cgroup, |
2326 | .gpl_only = false, | 2311 | .gpl_only = false, |
2327 | .ret_type = RET_INTEGER, | 2312 | .ret_type = RET_INTEGER, |
2328 | .arg1_type = ARG_PTR_TO_CTX, | 2313 | .arg1_type = ARG_PTR_TO_CTX, |
@@ -2402,8 +2387,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id) | |||
2402 | case BPF_FUNC_get_smp_processor_id: | 2387 | case BPF_FUNC_get_smp_processor_id: |
2403 | return &bpf_get_smp_processor_id_proto; | 2388 | return &bpf_get_smp_processor_id_proto; |
2404 | #ifdef CONFIG_SOCK_CGROUP_DATA | 2389 | #ifdef CONFIG_SOCK_CGROUP_DATA |
2405 | case BPF_FUNC_skb_in_cgroup: | 2390 | case BPF_FUNC_skb_under_cgroup: |
2406 | return &bpf_skb_in_cgroup_proto; | 2391 | return &bpf_skb_under_cgroup_proto; |
2407 | #endif | 2392 | #endif |
2408 | default: | 2393 | default: |
2409 | return sk_filter_func_proto(func_id); | 2394 | return sk_filter_func_proto(func_id); |