|
46 | 46 | #include <linux/seccomp.h>
|
47 | 47 | #include <linux/if_vlan.h>
|
48 | 48 | #include <linux/bpf.h>
|
| 49 | +#include <net/sch_generic.h> |
49 | 50 |
|
50 | 51 | /**
|
51 | 52 | * sk_filter - run a packet through a socket filter
|
@@ -1407,6 +1408,43 @@ const struct bpf_func_proto bpf_l4_csum_replace_proto = {
|
1407 | 1408 | .arg5_type = ARG_ANYTHING,
|
1408 | 1409 | };
|
1409 | 1410 |
|
| 1411 | +#define BPF_IS_REDIRECT_INGRESS(flags) ((flags) & 1) |
| 1412 | + |
| 1413 | +static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5) |
| 1414 | +{ |
| 1415 | + struct sk_buff *skb = (struct sk_buff *) (long) r1, *skb2; |
| 1416 | + struct net_device *dev; |
| 1417 | + |
| 1418 | + dev = dev_get_by_index_rcu(dev_net(skb->dev), ifindex); |
| 1419 | + if (unlikely(!dev)) |
| 1420 | + return -EINVAL; |
| 1421 | + |
| 1422 | + if (unlikely(!(dev->flags & IFF_UP))) |
| 1423 | + return -EINVAL; |
| 1424 | + |
| 1425 | + skb2 = skb_clone(skb, GFP_ATOMIC); |
| 1426 | + if (unlikely(!skb2)) |
| 1427 | + return -ENOMEM; |
| 1428 | + |
| 1429 | + if (G_TC_AT(skb2->tc_verd) & AT_INGRESS) |
| 1430 | + skb_push(skb2, skb2->mac_len); |
| 1431 | + |
| 1432 | + if (BPF_IS_REDIRECT_INGRESS(flags)) |
| 1433 | + return dev_forward_skb(dev, skb2); |
| 1434 | + |
| 1435 | + skb2->dev = dev; |
| 1436 | + return dev_queue_xmit(skb2); |
| 1437 | +} |
| 1438 | + |
| 1439 | +const struct bpf_func_proto bpf_clone_redirect_proto = { |
| 1440 | + .func = bpf_clone_redirect, |
| 1441 | + .gpl_only = false, |
| 1442 | + .ret_type = RET_INTEGER, |
| 1443 | + .arg1_type = ARG_PTR_TO_CTX, |
| 1444 | + .arg2_type = ARG_ANYTHING, |
| 1445 | + .arg3_type = ARG_ANYTHING, |
| 1446 | +}; |
| 1447 | + |
1410 | 1448 | static const struct bpf_func_proto *
|
1411 | 1449 | sk_filter_func_proto(enum bpf_func_id func_id)
|
1412 | 1450 | {
|
@@ -1440,6 +1478,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
|
1440 | 1478 | return &bpf_l3_csum_replace_proto;
|
1441 | 1479 | case BPF_FUNC_l4_csum_replace:
|
1442 | 1480 | return &bpf_l4_csum_replace_proto;
|
| 1481 | + case BPF_FUNC_clone_redirect: |
| 1482 | + return &bpf_clone_redirect_proto; |
1443 | 1483 | default:
|
1444 | 1484 | return sk_filter_func_proto(func_id);
|
1445 | 1485 | }
|
|
0 commit comments