xref: /aosp_15_r20/external/bcc/tests/python/test_clang_complex.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker // Copyright (c) PLUMgrid, Inc.
2*387f9dfdSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License")
3*387f9dfdSAndroid Build Coastguard Worker 
4*387f9dfdSAndroid Build Coastguard Worker #include <bcc/proto.h>
5*387f9dfdSAndroid Build Coastguard Worker 
6*387f9dfdSAndroid Build Coastguard Worker // hash
7*387f9dfdSAndroid Build Coastguard Worker struct FwdKey {
8*387f9dfdSAndroid Build Coastguard Worker   u32 dip:32;
9*387f9dfdSAndroid Build Coastguard Worker };
10*387f9dfdSAndroid Build Coastguard Worker struct FwdLeaf {
11*387f9dfdSAndroid Build Coastguard Worker   u32 fwd_idx:32;
12*387f9dfdSAndroid Build Coastguard Worker };
13*387f9dfdSAndroid Build Coastguard Worker BPF_HASH(fwd_map, struct FwdKey, struct FwdLeaf, 1);
14*387f9dfdSAndroid Build Coastguard Worker 
15*387f9dfdSAndroid Build Coastguard Worker // array
16*387f9dfdSAndroid Build Coastguard Worker struct ConfigLeaf {
17*387f9dfdSAndroid Build Coastguard Worker   u32 bpfdev_ip;
18*387f9dfdSAndroid Build Coastguard Worker   u32 slave_ip;
19*387f9dfdSAndroid Build Coastguard Worker };
20*387f9dfdSAndroid Build Coastguard Worker BPF_TABLE("array", u32, struct ConfigLeaf, config_map, 1);
21*387f9dfdSAndroid Build Coastguard Worker 
22*387f9dfdSAndroid Build Coastguard Worker // hash
23*387f9dfdSAndroid Build Coastguard Worker struct MacaddrKey {
24*387f9dfdSAndroid Build Coastguard Worker   u32 ip;
25*387f9dfdSAndroid Build Coastguard Worker };
26*387f9dfdSAndroid Build Coastguard Worker struct MacaddrLeaf {
27*387f9dfdSAndroid Build Coastguard Worker   u64 mac;
28*387f9dfdSAndroid Build Coastguard Worker };
29*387f9dfdSAndroid Build Coastguard Worker BPF_HASH(macaddr_map, struct MacaddrKey, struct MacaddrLeaf, 11);
30*387f9dfdSAndroid Build Coastguard Worker 
31*387f9dfdSAndroid Build Coastguard Worker // hash
32*387f9dfdSAndroid Build Coastguard Worker struct SlaveKey {
33*387f9dfdSAndroid Build Coastguard Worker   u32 slave_ip;
34*387f9dfdSAndroid Build Coastguard Worker };
35*387f9dfdSAndroid Build Coastguard Worker struct SlaveLeaf {
36*387f9dfdSAndroid Build Coastguard Worker   u32 slave_ifindex;
37*387f9dfdSAndroid Build Coastguard Worker };
38*387f9dfdSAndroid Build Coastguard Worker BPF_HASH(slave_map, struct SlaveKey, struct SlaveLeaf, 10);
39*387f9dfdSAndroid Build Coastguard Worker 
handle_packet(struct __sk_buff * skb)40*387f9dfdSAndroid Build Coastguard Worker int handle_packet(struct __sk_buff *skb) {
41*387f9dfdSAndroid Build Coastguard Worker   int ret = 0;
42*387f9dfdSAndroid Build Coastguard Worker   u8 *cursor = 0;
43*387f9dfdSAndroid Build Coastguard Worker 
44*387f9dfdSAndroid Build Coastguard Worker   if (skb->pkt_type == 0) {
45*387f9dfdSAndroid Build Coastguard Worker     // tx
46*387f9dfdSAndroid Build Coastguard Worker     // make sure configured
47*387f9dfdSAndroid Build Coastguard Worker     u32 slave_ip;
48*387f9dfdSAndroid Build Coastguard Worker 
49*387f9dfdSAndroid Build Coastguard Worker     u32 cfg_key = 0;
50*387f9dfdSAndroid Build Coastguard Worker     struct ConfigLeaf *cfg_leaf = config_map.lookup(&cfg_key);
51*387f9dfdSAndroid Build Coastguard Worker     if (cfg_leaf) {
52*387f9dfdSAndroid Build Coastguard Worker       slave_ip = cfg_leaf->slave_ip;
53*387f9dfdSAndroid Build Coastguard Worker     } else {
54*387f9dfdSAndroid Build Coastguard Worker       return 0xffffffff;
55*387f9dfdSAndroid Build Coastguard Worker     }
56*387f9dfdSAndroid Build Coastguard Worker 
57*387f9dfdSAndroid Build Coastguard Worker     // make sure slave configured
58*387f9dfdSAndroid Build Coastguard Worker     // tx, default to the single slave
59*387f9dfdSAndroid Build Coastguard Worker     struct SlaveKey slave_key = {.slave_ip = slave_ip};
60*387f9dfdSAndroid Build Coastguard Worker     struct SlaveLeaf *slave_leaf = slave_map.lookup(&slave_key);
61*387f9dfdSAndroid Build Coastguard Worker     if (slave_leaf) {
62*387f9dfdSAndroid Build Coastguard Worker       ret = slave_leaf->slave_ifindex;
63*387f9dfdSAndroid Build Coastguard Worker     } else {
64*387f9dfdSAndroid Build Coastguard Worker       return 0xffffffff;
65*387f9dfdSAndroid Build Coastguard Worker     }
66*387f9dfdSAndroid Build Coastguard Worker   } else {
67*387f9dfdSAndroid Build Coastguard Worker     // rx, default to stack
68*387f9dfdSAndroid Build Coastguard Worker     ret = 0;
69*387f9dfdSAndroid Build Coastguard Worker   }
70*387f9dfdSAndroid Build Coastguard Worker 
71*387f9dfdSAndroid Build Coastguard Worker   struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
72*387f9dfdSAndroid Build Coastguard Worker   switch (ethernet->type) {
73*387f9dfdSAndroid Build Coastguard Worker     case ETH_P_IP: goto ip;
74*387f9dfdSAndroid Build Coastguard Worker     case ETH_P_ARP: goto arp;
75*387f9dfdSAndroid Build Coastguard Worker     case ETH_P_8021Q: goto dot1q;
76*387f9dfdSAndroid Build Coastguard Worker     default: goto EOP;
77*387f9dfdSAndroid Build Coastguard Worker   }
78*387f9dfdSAndroid Build Coastguard Worker 
79*387f9dfdSAndroid Build Coastguard Worker   dot1q: {
80*387f9dfdSAndroid Build Coastguard Worker     struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
81*387f9dfdSAndroid Build Coastguard Worker     switch (dot1q->type) {
82*387f9dfdSAndroid Build Coastguard Worker       case ETH_P_IP: goto ip;
83*387f9dfdSAndroid Build Coastguard Worker       case ETH_P_ARP: goto arp;
84*387f9dfdSAndroid Build Coastguard Worker       default: goto EOP;
85*387f9dfdSAndroid Build Coastguard Worker     }
86*387f9dfdSAndroid Build Coastguard Worker   }
87*387f9dfdSAndroid Build Coastguard Worker 
88*387f9dfdSAndroid Build Coastguard Worker   arp: {
89*387f9dfdSAndroid Build Coastguard Worker     struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
90*387f9dfdSAndroid Build Coastguard Worker     if (skb->pkt_type) {
91*387f9dfdSAndroid Build Coastguard Worker       if (arp->oper == 1) {
92*387f9dfdSAndroid Build Coastguard Worker         struct MacaddrKey mac_key = {.ip=arp->spa};
93*387f9dfdSAndroid Build Coastguard Worker         struct MacaddrLeaf mac_leaf = {.mac=arp->sha};
94*387f9dfdSAndroid Build Coastguard Worker         macaddr_map.update(&mac_key, &mac_leaf);
95*387f9dfdSAndroid Build Coastguard Worker       }
96*387f9dfdSAndroid Build Coastguard Worker     }
97*387f9dfdSAndroid Build Coastguard Worker     goto EOP;
98*387f9dfdSAndroid Build Coastguard Worker   }
99*387f9dfdSAndroid Build Coastguard Worker 
100*387f9dfdSAndroid Build Coastguard Worker   struct ip_t *ip;
101*387f9dfdSAndroid Build Coastguard Worker   ip: {
102*387f9dfdSAndroid Build Coastguard Worker     ip = cursor_advance(cursor, sizeof(*ip));
103*387f9dfdSAndroid Build Coastguard Worker     switch (ip->nextp) {
104*387f9dfdSAndroid Build Coastguard Worker       case 6: goto tcp;
105*387f9dfdSAndroid Build Coastguard Worker       case 17: goto udp;
106*387f9dfdSAndroid Build Coastguard Worker       default: goto EOP;
107*387f9dfdSAndroid Build Coastguard Worker     }
108*387f9dfdSAndroid Build Coastguard Worker   }
109*387f9dfdSAndroid Build Coastguard Worker   tcp: {
110*387f9dfdSAndroid Build Coastguard Worker     struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
111*387f9dfdSAndroid Build Coastguard Worker     goto EOP;
112*387f9dfdSAndroid Build Coastguard Worker   }
113*387f9dfdSAndroid Build Coastguard Worker   udp: {
114*387f9dfdSAndroid Build Coastguard Worker     struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
115*387f9dfdSAndroid Build Coastguard Worker     if (udp->dport != 5000) {
116*387f9dfdSAndroid Build Coastguard Worker        goto EOP;
117*387f9dfdSAndroid Build Coastguard Worker     }
118*387f9dfdSAndroid Build Coastguard Worker     if (skb->pkt_type) {
119*387f9dfdSAndroid Build Coastguard Worker       // lookup and then forward
120*387f9dfdSAndroid Build Coastguard Worker       struct FwdKey fwd_key = {.dip=ip->dst};
121*387f9dfdSAndroid Build Coastguard Worker       struct FwdLeaf *fwd_val = fwd_map.lookup(&fwd_key);
122*387f9dfdSAndroid Build Coastguard Worker       if (fwd_val) {
123*387f9dfdSAndroid Build Coastguard Worker          return fwd_val->fwd_idx;
124*387f9dfdSAndroid Build Coastguard Worker       }
125*387f9dfdSAndroid Build Coastguard Worker     } else {
126*387f9dfdSAndroid Build Coastguard Worker       // rewrite the packet and send to a pre-configured index if needed
127*387f9dfdSAndroid Build Coastguard Worker       u32 new_ip;
128*387f9dfdSAndroid Build Coastguard Worker       u32 old_ip;
129*387f9dfdSAndroid Build Coastguard Worker       u64 src_mac;
130*387f9dfdSAndroid Build Coastguard Worker       u64 dst_mac;
131*387f9dfdSAndroid Build Coastguard Worker 
132*387f9dfdSAndroid Build Coastguard Worker       u32 cfg_key = 0;
133*387f9dfdSAndroid Build Coastguard Worker       struct ConfigLeaf *cfg_leaf = config_map.lookup(&cfg_key);
134*387f9dfdSAndroid Build Coastguard Worker       if (cfg_leaf) {
135*387f9dfdSAndroid Build Coastguard Worker         struct MacaddrKey mac_key = {.ip = cfg_leaf->bpfdev_ip};
136*387f9dfdSAndroid Build Coastguard Worker         struct MacaddrLeaf *mac_leaf;
137*387f9dfdSAndroid Build Coastguard Worker 
138*387f9dfdSAndroid Build Coastguard Worker         mac_key.ip = cfg_leaf->bpfdev_ip;
139*387f9dfdSAndroid Build Coastguard Worker         mac_leaf = macaddr_map.lookup(&mac_key);
140*387f9dfdSAndroid Build Coastguard Worker         if (mac_leaf) {
141*387f9dfdSAndroid Build Coastguard Worker           src_mac = mac_leaf->mac;
142*387f9dfdSAndroid Build Coastguard Worker         } else {
143*387f9dfdSAndroid Build Coastguard Worker           goto EOP;
144*387f9dfdSAndroid Build Coastguard Worker         }
145*387f9dfdSAndroid Build Coastguard Worker 
146*387f9dfdSAndroid Build Coastguard Worker         mac_key.ip = cfg_leaf->slave_ip;
147*387f9dfdSAndroid Build Coastguard Worker         mac_leaf = macaddr_map.lookup(&mac_key);
148*387f9dfdSAndroid Build Coastguard Worker         if (mac_leaf) {
149*387f9dfdSAndroid Build Coastguard Worker           dst_mac = mac_leaf->mac;
150*387f9dfdSAndroid Build Coastguard Worker         } else {
151*387f9dfdSAndroid Build Coastguard Worker           goto EOP;
152*387f9dfdSAndroid Build Coastguard Worker         }
153*387f9dfdSAndroid Build Coastguard Worker 
154*387f9dfdSAndroid Build Coastguard Worker         // rewrite ethernet header
155*387f9dfdSAndroid Build Coastguard Worker         ethernet->dst = dst_mac;
156*387f9dfdSAndroid Build Coastguard Worker         ethernet->src = src_mac;
157*387f9dfdSAndroid Build Coastguard Worker 
158*387f9dfdSAndroid Build Coastguard Worker         // ip & udp checksum
159*387f9dfdSAndroid Build Coastguard Worker         incr_cksum_l4(&udp->crc, ip->src, cfg_leaf->bpfdev_ip, 1);
160*387f9dfdSAndroid Build Coastguard Worker         incr_cksum_l4(&udp->crc, ip->dst, cfg_leaf->slave_ip, 1);
161*387f9dfdSAndroid Build Coastguard Worker 
162*387f9dfdSAndroid Build Coastguard Worker         // rewrite ip src/dst fields
163*387f9dfdSAndroid Build Coastguard Worker         ip->src = cfg_leaf->bpfdev_ip;
164*387f9dfdSAndroid Build Coastguard Worker         ip->dst = cfg_leaf->slave_ip;
165*387f9dfdSAndroid Build Coastguard Worker       }
166*387f9dfdSAndroid Build Coastguard Worker     }
167*387f9dfdSAndroid Build Coastguard Worker     goto EOP;
168*387f9dfdSAndroid Build Coastguard Worker   }
169*387f9dfdSAndroid Build Coastguard Worker 
170*387f9dfdSAndroid Build Coastguard Worker EOP:
171*387f9dfdSAndroid Build Coastguard Worker   return ret;
172*387f9dfdSAndroid Build Coastguard Worker }
173