Skip to content

Instantly share code, notes, and snippets.

@williamtu
Created February 8, 2017 20:20
Show Gist options
  • Select an option

  • Save williamtu/5a09b60a951ee5fc062328766403ab4b to your computer and use it in GitHub Desktop.

Select an option

Save williamtu/5a09b60a951ee5fc062328766403ab4b to your computer and use it in GitHub Desktop.

Revisions

  1. williamtu created this gist Feb 8, 2017.
    922 changes: 922 additions & 0 deletions xdp7.S
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,922 @@

    xdp7.o: file format ELF64-BPF

    Disassembly of section prog:
    ebpf_filter:
    ; int ebpf_filter(struct xdp_md* skb){
    0: r6 = r1
    ; void* ebpf_packetEnd = ((void*)(long)skb->data_end);
    1: r3 = *(u32 *)(r6 + 4)
    ; void* ebpf_packetStart = ((void*)(long)skb->data);
    2: r2 = *(u32 *)(r6 + 0)
    3: r7 = 0
    ; u32 ebpf_zero = 0;
    4: *(u32 *)(r10 - 4) = r7
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 112)) {
    5: r1 = r2
    6: r1 += 14
    7: if r1 > r3 goto 735
    8: r8 = 0
    ; hd.ethernet.destination[5] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5) >> 0));
    9: r1 = *(u8 *)(r2 + 11)
    ; hd.ethernet.destination[4] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4) >> 0));
    10: *(u64 *)(r10 - 408) = r1
    11: r1 = *(u8 *)(r2 + 10)
    ; hd.ethernet.destination[3] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3) >> 0));
    12: *(u64 *)(r10 - 416) = r1
    13: r1 = *(u8 *)(r2 + 9)
    ; hd.ethernet.destination[2] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2) >> 0));
    14: *(u64 *)(r10 - 424) = r1
    15: r1 = *(u8 *)(r2 + 8)
    ; hd.ethernet.destination[1] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1) >> 0));
    16: *(u64 *)(r10 - 432) = r1
    17: r1 = *(u8 *)(r2 + 7)
    ; hd.ethernet.destination[0] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0) >> 0));
    18: *(u64 *)(r10 - 440) = r1
    19: r1 = *(u8 *)(r2 + 6)
    ; hd.ethernet.source[5] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5) >> 0));
    20: *(u64 *)(r10 - 448) = r1
    21: r1 = *(u8 *)(r2 + 5)
    ; hd.ethernet.source[4] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4) >> 0));
    22: *(u64 *)(r10 - 456) = r1
    23: r1 = *(u8 *)(r2 + 4)
    ; hd.ethernet.source[3] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3) >> 0));
    24: *(u64 *)(r10 - 464) = r1
    25: r1 = *(u8 *)(r2 + 3)
    ; hd.ethernet.source[2] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2) >> 0));
    26: *(u64 *)(r10 - 472) = r1
    27: r1 = *(u8 *)(r2 + 2)
    ; hd.ethernet.source[1] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1) >> 0));
    28: *(u64 *)(r10 - 480) = r1
    29: r1 = *(u8 *)(r2 + 1)
    ; hd.ethernet.source[0] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0) >> 0));
    30: *(u64 *)(r10 - 488) = r1
    31: r1 = *(u8 *)(r2 + 0)
    ; hd.ethernet.protocol = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    32: *(u64 *)(r10 - 496) = r1
    33: r1 = *(u16 *)(r2 + 12)
    ; switch (hd.ethernet.protocol) {
    34: r4 = r1
    35: r4 <<= 8
    36: *(u64 *)(r10 - 504) = r1
    ; hd.ethernet.protocol = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    37: r1 >>= 8
    38: *(u64 *)(r10 - 512) = r1
    ; switch (hd.ethernet.protocol) {
    39: r1 |= r4
    40: *(u64 *)(r10 - 32) = r1
    41: r4 = r1
    42: r4 &= 65535
    43: r5 = 0
    44: *(u64 *)(r10 - 112) = r5
    45: r5 = 0
    46: *(u64 *)(r10 - 120) = r5
    47: r5 = 0
    48: *(u64 *)(r10 - 128) = r5
    49: r5 = 0
    50: *(u64 *)(r10 - 96) = r5
    51: r5 = 0
    52: *(u64 *)(r10 - 88) = r5
    53: r5 = 0
    54: *(u64 *)(r10 - 104) = r5
    55: r7 = 0
    56: r1 = 0
    57: *(u64 *)(r10 - 352) = r1
    58: r1 = 0
    59: *(u64 *)(r10 - 336) = r1
    60: r1 = 0
    61: *(u64 *)(r10 - 344) = r1
    62: r5 = 0
    63: *(u64 *)(r10 - 288) = r5
    64: r5 = 0
    65: *(u64 *)(r10 - 296) = r5
    66: r1 = 0
    67: *(u64 *)(r10 - 320) = r1
    68: r1 = 0
    69: *(u64 *)(r10 - 328) = r1
    70: r5 = 0
    71: *(u64 *)(r10 - 272) = r5
    72: r5 = 0
    73: *(u64 *)(r10 - 280) = r5
    74: r1 = 0
    75: *(u64 *)(r10 - 304) = r1
    76: r1 = 0
    77: *(u64 *)(r10 - 312) = r1
    78: r5 = 0
    79: *(u64 *)(r10 - 256) = r5
    80: r5 = 0
    81: *(u64 *)(r10 - 264) = r5
    82: r5 = 0
    83: *(u64 *)(r10 - 240) = r5
    84: r5 = 0
    85: *(u64 *)(r10 - 248) = r5
    86: r5 = 0
    87: *(u64 *)(r10 - 224) = r5
    88: r5 = 0
    89: *(u64 *)(r10 - 232) = r5
    90: r5 = 0
    91: r0 = 0
    92: *(u64 *)(r10 - 392) = r0
    93: r0 = 0
    94: *(u64 *)(r10 - 384) = r0
    95: r0 = 0
    96: r9 = 0
    97: *(u64 *)(r10 - 176) = r9
    98: r9 = 0
    99: *(u64 *)(r10 - 80) = r9
    100: r9 = 0
    101: *(u64 *)(r10 - 136) = r9
    102: r9 = 0
    103: *(u64 *)(r10 - 152) = r9
    104: r1 = 0
    105: *(u64 *)(r10 - 72) = r1
    106: r9 = 0
    107: *(u64 *)(r10 - 144) = r9
    108: r1 = 0
    109: *(u64 *)(r10 - 360) = r1
    110: r1 = 0
    111: *(u64 *)(r10 - 368) = r1
    112: r1 = 0
    113: *(u64 *)(r10 - 376) = r1
    114: r1 = 0
    115: *(u64 *)(r10 - 56) = r1
    116: r1 = 0
    117: *(u64 *)(r10 - 216) = r1
    118: r1 = 0
    119: *(u64 *)(r10 - 64) = r1
    120: r1 = 0
    121: *(u64 *)(r10 - 40) = r1
    122: r9 = 0
    123: *(u64 *)(r10 - 168) = r9
    124: r9 = 0
    125: *(u64 *)(r10 - 184) = r9
    126: r9 = 0
    127: *(u64 *)(r10 - 160) = r9
    128: r1 = 0
    129: *(u64 *)(r10 - 208) = r1
    130: r1 = 0
    131: *(u64 *)(r10 - 200) = r1
    132: r9 = 0
    133: r1 = 0
    134: *(u64 *)(r10 - 48) = r1
    135: r1 = 0
    136: *(u64 *)(r10 - 192) = r1
    137: if r4 != 2048 goto 313
    138: r7 = 0
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    139: r4 = r2
    140: r4 += 34
    141: if r4 > r3 goto 601
    142: r1 = 1
    ; hd.ipv4.ttl = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    143: *(u64 *)(r10 - 56) = r1
    144: r1 = *(u8 *)(r2 + 22)
    ; hd.ipv4.diffserv = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    145: *(u64 *)(r10 - 64) = r1
    146: r4 = *(u8 *)(r2 + 15)
    ; hd.ipv4.dstAddr = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    147: *(u64 *)(r10 - 160) = r4
    148: r4 = *(u32 *)(r2 + 30)
    149: r5 = r4
    150: bswap16 r5
    151: *(u64 *)(r10 - 96) = r5
    152: r5 = r4
    153: bswap32 r5
    154: *(u64 *)(r10 - 104) = r5
    ; hd.ipv4.srcAddr = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    155: r5 = *(u32 *)(r2 + 26)
    156: r1 = r5
    157: bswap16 r1
    158: *(u64 *)(r10 - 400) = r1
    159: r7 = r5
    160: bswap32 r7
    161: *(u64 *)(r10 - 120) = r7
    ; hd.ipv4.hdrChecksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    162: r9 = *(u16 *)(r2 + 24)
    163: r0 = r9
    164: bswap16 r0
    165: *(u64 *)(r10 - 136) = r0
    ; hd.ipv4.fragOffset = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13));
    166: r0 = *(u16 *)(r2 + 20)
    167: r7 = r0
    168: r7 &= 31
    169: *(u64 *)(r10 - 40) = r7
    170: r0 >>= 8
    171: *(u64 *)(r10 - 144) = r0
    ; hd.ipv4.flags = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3));
    172: r0 = *(u8 *)(r2 + 20)
    173: r0 >>= 5
    174: *(u64 *)(r10 - 168) = r0
    ; hd.ipv4.identification = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    175: r8 = *(u16 *)(r2 + 18)
    176: r0 = r8
    177: bswap16 r0
    178: *(u64 *)(r10 - 184) = r0
    ; hd.ipv4.totalLen = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    179: r1 = *(u16 *)(r2 + 16)
    180: r0 = r1
    181: bswap16 r0
    182: *(u64 *)(r10 - 48) = r0
    ; hd.ipv4.version = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4));
    183: r0 = *(u8 *)(r2 + 14)
    ; hd.ipv4.ihl = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4));
    184: r7 = r0
    185: r7 &= 15
    186: *(u64 *)(r10 - 208) = r7
    ; hd.ipv4.version = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4));
    187: r0 >>= 4
    188: *(u64 *)(r10 - 200) = r0
    ; hd.ipv4.dstAddr = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    189: bswap64 r4
    190: r7 = r4
    191: r7 >>= 56
    192: *(u64 *)(r10 - 128) = r7
    193: r4 >>= 40
    194: *(u64 *)(r10 - 88) = r4
    ; hd.ipv4.srcAddr = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    195: bswap64 r5
    196: r4 = r5
    197: r4 >>= 56
    198: *(u64 *)(r10 - 176) = r4
    199: r5 >>= 40
    200: *(u64 *)(r10 - 112) = r5
    ; hd.ipv4.hdrChecksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    201: bswap64 r9
    202: r9 >>= 56
    203: *(u64 *)(r10 - 152) = r9
    204: r9 = r8
    ; hd.ipv4.identification = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    205: bswap64 r9
    206: r9 >>= 56
    ; hd.ipv4.totalLen = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    207: bswap64 r1
    208: r1 >>= 56
    209: *(u64 *)(r10 - 192) = r1
    ; hd.ipv4.protocol = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    210: r1 = *(u8 *)(r2 + 23)
    ; switch (hd.ipv4.protocol) {
    211: *(u64 *)(r10 - 216) = r1
    212: if r1 == 17 goto 182
    213: if r1 == 6 goto 113
    214: r7 = 0
    215: r4 = 0
    216: *(u64 *)(r10 - 352) = r4
    217: r4 = 0
    218: *(u64 *)(r10 - 336) = r4
    219: r4 = 0
    220: *(u64 *)(r10 - 344) = r4
    221: r4 = 0
    222: *(u64 *)(r10 - 288) = r4
    223: r4 = 0
    224: *(u64 *)(r10 - 296) = r4
    225: r4 = 0
    226: *(u64 *)(r10 - 320) = r4
    227: r4 = 0
    228: *(u64 *)(r10 - 328) = r4
    229: r4 = 0
    230: *(u64 *)(r10 - 272) = r4
    231: r4 = 0
    232: *(u64 *)(r10 - 280) = r4
    233: r4 = 0
    234: *(u64 *)(r10 - 304) = r4
    235: r4 = 0
    236: *(u64 *)(r10 - 312) = r4
    237: r4 = 0
    238: *(u64 *)(r10 - 256) = r4
    239: r4 = 0
    240: *(u64 *)(r10 - 264) = r4
    241: r4 = 0
    242: *(u64 *)(r10 - 240) = r4
    243: r4 = 0
    244: *(u64 *)(r10 - 248) = r4
    245: r4 = 0
    246: *(u64 *)(r10 - 224) = r4
    247: r4 = 0
    248: *(u64 *)(r10 - 232) = r4
    249: r5 = 0
    250: r4 = 0
    251: *(u64 *)(r10 - 392) = r4
    252: r4 = 0
    253: *(u64 *)(r10 - 384) = r4
    254: r0 = 0
    255: r4 = 0
    256: *(u64 *)(r10 - 80) = r4
    257: r4 = 0
    258: *(u64 *)(r10 - 72) = r4
    259: r4 = 0
    260: *(u64 *)(r10 - 360) = r4
    261: r4 = 0
    262: *(u64 *)(r10 - 368) = r4
    263: r4 = 0
    264: *(u64 *)(r10 - 376) = r4
    265: r4 = *(u64 *)(r10 - 40)
    266: r4 = *(u64 *)(r10 - 48)
    267: r8 = *(u64 *)(r10 - 400)
    268: if r1 != 1 goto 182
    269: r7 = 0
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 32)) {
    270: r4 = r2
    271: r4 += 38
    272: if r4 > r3 goto 470
    273: r3 = 1
    274: *(u64 *)(r10 - 80) = r3
    275: r7 = 0
    ; hd.icmp.hdrChecksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    276: r3 = *(u16 *)(r2 + 36)
    277: *(u64 *)(r10 - 384) = r3
    278: r0 = r3
    279: r0 >>= 8
    ; hd.icmp.typeCode = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    280: r5 = *(u16 *)(r2 + 34)
    281: r2 = r5
    282: r2 >>= 8
    283: *(u64 *)(r10 - 392) = r2
    284: r1 = 0
    285: *(u64 *)(r10 - 352) = r1
    286: r1 = 0
    287: *(u64 *)(r10 - 336) = r1
    288: r1 = 0
    289: *(u64 *)(r10 - 344) = r1
    290: r2 = 0
    291: *(u64 *)(r10 - 288) = r2
    292: r2 = 0
    293: *(u64 *)(r10 - 296) = r2
    294: r1 = 0
    295: *(u64 *)(r10 - 320) = r1
    296: r1 = 0
    297: *(u64 *)(r10 - 328) = r1
    298: r2 = 0
    299: *(u64 *)(r10 - 272) = r2
    300: r2 = 0
    301: *(u64 *)(r10 - 280) = r2
    302: r1 = 0
    303: *(u64 *)(r10 - 304) = r1
    304: r1 = 0
    305: *(u64 *)(r10 - 312) = r1
    306: r2 = 0
    307: *(u64 *)(r10 - 256) = r2
    308: r2 = 0
    309: *(u64 *)(r10 - 264) = r2
    310: r2 = 0
    311: *(u64 *)(r10 - 240) = r2
    312: r2 = 0
    313: *(u64 *)(r10 - 248) = r2
    314: r2 = 0
    315: *(u64 *)(r10 - 224) = r2
    316: r2 = 0
    317: *(u64 *)(r10 - 232) = r2
    318: r1 = 0
    319: *(u64 *)(r10 - 72) = r1
    320: r1 = 0
    321: *(u64 *)(r10 - 360) = r1
    322: r1 = 0
    323: *(u64 *)(r10 - 368) = r1
    324: r1 = 0
    325: *(u64 *)(r10 - 376) = r1
    326: goto 65

    LBB0_9:
    327: r7 = 0
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    328: r4 = r2
    329: r4 += 54
    330: r1 = *(u64 *)(r10 - 40)
    331: r1 = *(u64 *)(r10 - 48)
    332: r8 = *(u64 *)(r10 - 400)
    333: if r4 > r3 goto 409
    334: r1 = 1
    335: *(u64 *)(r10 - 72) = r1
    336: r5 = 0
    ; hd.tcp.flags = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    337: r1 = *(u8 *)(r2 + 47)
    ; hd.tcp.ackNo = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    338: *(u64 *)(r10 - 360) = r1
    339: r4 = *(u32 *)(r2 + 42)
    ; goto accept;
    340: r3 = r4
    341: r3 >>= 8
    342: *(u64 *)(r10 - 280) = r3
    ; hd.tcp.seqNo = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    343: r0 = *(u32 *)(r2 + 38)
    ; goto accept;
    344: r3 = r0
    345: r3 >>= 8
    346: *(u64 *)(r10 - 296) = r3
    ; hd.tcp.urgentPtr = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    347: r3 = *(u16 *)(r2 + 52)
    348: *(u64 *)(r10 - 224) = r3
    349: r3 >>= 8
    350: *(u64 *)(r10 - 232) = r3
    ; hd.tcp.checksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    351: r3 = *(u16 *)(r2 + 50)
    352: *(u64 *)(r10 - 240) = r3
    353: r3 >>= 8
    354: *(u64 *)(r10 - 248) = r3
    ; hd.tcp.window = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    355: r3 = *(u16 *)(r2 + 48)
    356: *(u64 *)(r10 - 256) = r3
    357: r3 >>= 8
    358: *(u64 *)(r10 - 264) = r3
    ; hd.tcp.ackNo = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    359: r1 = r4
    360: r1 >>= 24
    361: *(u64 *)(r10 - 312) = r1
    362: *(u64 *)(r10 - 272) = r4
    363: r4 >>= 16
    364: *(u64 *)(r10 - 304) = r4
    ; hd.tcp.seqNo = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    365: r1 = r0
    366: r1 >>= 24
    367: *(u64 *)(r10 - 328) = r1
    368: *(u64 *)(r10 - 288) = r0
    369: r0 >>= 16
    370: *(u64 *)(r10 - 320) = r0
    ; hd.tcp.dstPort = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    371: r1 = *(u16 *)(r2 + 36)
    372: *(u64 *)(r10 - 336) = r1
    373: r1 >>= 8
    374: *(u64 *)(r10 - 344) = r1
    ; hd.tcp.srcPort = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    375: r7 = *(u16 *)(r2 + 34)
    376: r1 = r7
    377: r1 >>= 8
    378: *(u64 *)(r10 - 352) = r1
    ; hd.tcp.dataOffset = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4));
    379: r2 = *(u8 *)(r2 + 46)
    ; hd.tcp.res = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4));
    380: r1 = r2
    381: r1 &= 15
    382: *(u64 *)(r10 - 368) = r1
    ; goto accept;
    383: r2 &= 240
    384: *(u64 *)(r10 - 376) = r2
    385: r2 = 0
    386: *(u64 *)(r10 - 392) = r2
    387: r2 = 0
    388: *(u64 *)(r10 - 384) = r2
    389: r0 = 0
    390: r2 = 0
    391: *(u64 *)(r10 - 80) = r2

    LBB0_8:
    392: r1 = 1
    393: *(u64 *)(r10 - 56) = r1
    394: goto 56

    LBB0_11:
    395: r7 = 0
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 64)) {
    396: r2 += 42
    397: r1 = 0
    398: *(u64 *)(r10 - 352) = r1
    399: r1 = 0
    400: *(u64 *)(r10 - 336) = r1
    401: r1 = 0
    402: *(u64 *)(r10 - 344) = r1
    403: r4 = 0
    404: *(u64 *)(r10 - 288) = r4
    405: r4 = 0
    406: *(u64 *)(r10 - 296) = r4
    407: r1 = 0
    408: *(u64 *)(r10 - 320) = r1
    409: r1 = 0
    410: *(u64 *)(r10 - 328) = r1
    411: r4 = 0
    412: *(u64 *)(r10 - 272) = r4
    413: r4 = 0
    414: *(u64 *)(r10 - 280) = r4
    415: r1 = 0
    416: *(u64 *)(r10 - 304) = r1
    417: r1 = 0
    418: *(u64 *)(r10 - 312) = r1
    419: r4 = 0
    420: *(u64 *)(r10 - 256) = r4
    421: r4 = 0
    422: *(u64 *)(r10 - 264) = r4
    423: r4 = 0
    424: *(u64 *)(r10 - 240) = r4
    425: r4 = 0
    426: *(u64 *)(r10 - 248) = r4
    427: r4 = 0
    428: *(u64 *)(r10 - 224) = r4
    429: r4 = 0
    430: *(u64 *)(r10 - 232) = r4
    431: r5 = 0
    432: r4 = 0
    433: *(u64 *)(r10 - 392) = r4
    434: r4 = 0
    435: *(u64 *)(r10 - 384) = r4
    436: r0 = 0
    437: r4 = 0
    438: *(u64 *)(r10 - 80) = r4
    439: r1 = 0
    440: *(u64 *)(r10 - 72) = r1
    441: r1 = 0
    442: *(u64 *)(r10 - 360) = r1
    443: r1 = 0
    444: *(u64 *)(r10 - 368) = r1
    445: r1 = 0
    446: *(u64 *)(r10 - 376) = r1
    447: r1 = *(u64 *)(r10 - 40)
    448: r1 = *(u64 *)(r10 - 48)
    449: r8 = *(u64 *)(r10 - 400)
    450: if r2 > r3 goto 292

    LBB0_12:
    451: *(u64 *)(r10 - 528) = r0
    452: *(u64 *)(r10 - 400) = r8
    453: *(u64 *)(r10 - 520) = r5
    ; key.field0 = hd.ethernet.protocol;
    454: r1 = *(u64 *)(r10 - 32)
    455: *(u16 *)(r10 - 24) = r1
    456: r2 = r10
    457: r2 += -24
    ; value = bpf_map_lookup_elem(&dstmactable, &key);
    458: r1 = 0ll
    460: call 1
    ; if (value == NULL) {
    461: if r0 != 0 goto 6
    462: r2 = r10
    463: r2 += -4
    ; value = bpf_map_lookup_elem(&dstmactable_defaultAction, &ebpf_zero);
    464: r1 = 0ll
    466: call 1
    ; if (value != NULL) {
    467: if r0 == 0 goto 274

    LBB0_14:
    468: r1 = 0
    469: r5 = 4
    ; switch (value->action) {
    470: r3 = *(u32 *)(r0 + 0)
    471: r2 = 0
    472: if r3 == 0 goto 3
    473: if r3 != 1 goto 268
    474: r2 = 1
    475: r5 = *(u64 *)(r10 - 64)

    LBB0_17:
    ; xout.output_port = 0;
    476: *(u32 *)(r10 - 12) = r1
    ; xout.drop = xoutdrop;
    477: *(u8 *)(r10 - 16) = r2
    ; xout.output_port = 0;
    478: r3 = r10
    479: r3 += -12
    ; ebpf_packetEnd = ((void*)(long)skb->data_end);
    480: r2 = *(u32 *)(r6 + 4)
    ; ebpf_packetStart = ((void*)(long)skb->data);
    481: r1 = *(u32 *)(r6 + 0)
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 112)) {
    482: r4 = r1
    483: r4 += 14
    484: if r4 > r2 goto 245
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    485: r4 = *(u64 *)(r10 - 496)
    486: *(u8 *)(r1 + 0) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    487: r4 = *(u64 *)(r10 - 488)
    488: *(u8 *)(r1 + 1) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    489: r4 = *(u64 *)(r10 - 480)
    490: *(u8 *)(r1 + 2) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    491: r4 = *(u64 *)(r10 - 472)
    492: *(u8 *)(r1 + 3) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte) << 0);
    493: r4 = *(u64 *)(r10 - 464)
    494: *(u8 *)(r1 + 4) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte) << 0);
    495: r4 = *(u64 *)(r10 - 456)
    496: *(u8 *)(r1 + 5) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    497: r4 = *(u64 *)(r10 - 448)
    498: *(u8 *)(r1 + 6) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    499: r4 = *(u64 *)(r10 - 440)
    500: *(u8 *)(r1 + 7) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    501: r4 = *(u64 *)(r10 - 432)
    502: *(u8 *)(r1 + 8) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    503: r4 = *(u64 *)(r10 - 424)
    504: *(u8 *)(r1 + 9) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte) << 0);
    505: r4 = *(u64 *)(r10 - 416)
    506: *(u8 *)(r1 + 10) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte) << 0);
    507: r4 = *(u64 *)(r10 - 408)
    508: *(u8 *)(r1 + 11) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    509: r4 = *(u64 *)(r10 - 504)
    510: *(u8 *)(r1 + 12) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    511: r4 = *(u64 *)(r10 - 512)
    512: *(u8 *)(r1 + 13) = r4
    513: r4 = 112
    ; if (hd.ipv4.ebpf_valid) {
    514: r0 = *(u64 *)(r10 - 56)
    515: if r0 == 0 goto 50
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    516: r4 = r1
    517: r4 += 34
    518: if r4 > r2 goto 211
    519: r4 = *(u64 *)(r10 - 200)
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 4);
    520: r4 <<= 4
    ; write_partial(ebpf_packetStart + BYTES(ebpf_packetOffsetInBits) + 0, 4, (ebpf_byte) << 4);
    521: r0 = *(u64 *)(r10 - 208)
    522: r4 |= r0
    523: *(u8 *)(r1 + 14) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    524: r4 = *(u64 *)(r10 - 160)
    525: *(u8 *)(r1 + 15) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    526: r4 = *(u64 *)(r10 - 192)
    527: *(u8 *)(r1 + 16) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    528: r4 = *(u64 *)(r10 - 48)
    529: *(u8 *)(r1 + 17) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    530: *(u8 *)(r1 + 18) = r9
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    531: r4 = *(u64 *)(r10 - 184)
    532: *(u8 *)(r1 + 19) = r4
    533: r0 = *(u64 *)(r10 - 168)
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 5);
    534: r0 <<= 5
    535: r4 = *(u64 *)(r10 - 144)
    ; write_partial(ebpf_packetStart + BYTES(ebpf_packetOffsetInBits) + 0, 3, (ebpf_byte) << 3);
    536: r4 >>= 2
    537: r4 &= 7
    538: r0 |= r4
    539: *(u8 *)(r1 + 20) = r0
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    540: r4 = *(u64 *)(r10 - 40)
    541: *(u8 *)(r1 + 21) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    542: *(u8 *)(r1 + 22) = r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    543: r4 = *(u64 *)(r10 - 216)
    544: *(u8 *)(r1 + 23) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    545: r4 = *(u64 *)(r10 - 152)
    546: *(u8 *)(r1 + 24) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    547: r4 = *(u64 *)(r10 - 136)
    548: *(u8 *)(r1 + 25) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    549: r4 = *(u64 *)(r10 - 176)
    550: *(u8 *)(r1 + 26) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    551: r4 = *(u64 *)(r10 - 400)
    552: *(u8 *)(r1 + 27) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    553: r4 = *(u64 *)(r10 - 112)
    554: *(u8 *)(r1 + 28) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    555: r4 = *(u64 *)(r10 - 120)
    556: *(u8 *)(r1 + 29) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    557: r4 = *(u64 *)(r10 - 128)
    558: *(u8 *)(r1 + 30) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    559: r4 = *(u64 *)(r10 - 96)
    560: *(u8 *)(r1 + 31) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    561: r4 = *(u64 *)(r10 - 88)
    562: *(u8 *)(r1 + 32) = r4
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    563: r4 = *(u64 *)(r10 - 104)
    564: *(u8 *)(r1 + 33) = r4
    565: r4 = 272

    LBB0_21:
    ; if (hd.tcp.ebpf_valid) {
    566: r5 = *(u64 *)(r10 - 72)
    567: if r5 == 0 goto 134
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    568: r0 = r4
    569: r0 += 160
    570: r5 = 4294967288ll
    572: r0 &= r5
    573: r0 >>= 3
    574: r6 = r1
    575: r6 += r0
    576: if r6 > r2 goto 153
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    577: r0 = r4
    578: r0 &= r5
    579: r0 >>= 3
    580: r6 = r1
    581: r6 += r0
    582: *(u8 *)(r6 + 0) = r7
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    583: r0 |= 1
    584: r6 = r1
    585: r6 += r0
    586: r0 = *(u64 *)(r10 - 352)
    587: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 16;
    588: r0 = r4
    589: r0 += 16
    590: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    591: r0 >>= 3
    592: r6 = r1
    593: r6 += r0
    594: r7 = *(u64 *)(r10 - 336)
    595: *(u8 *)(r6 + 0) = r7
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    596: r0 |= 1
    597: r6 = r1
    598: r6 += r0
    599: r0 = *(u64 *)(r10 - 344)
    600: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 16;
    601: r0 = r4
    602: r0 += 32
    603: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    604: r0 >>= 3
    605: r6 = r1
    606: r6 += r0
    607: r7 = *(u64 *)(r10 - 288)
    608: *(u8 *)(r6 + 0) = r7
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    609: r0 |= 1
    610: r7 = r1
    611: r7 += r0
    612: r0 = *(u64 *)(r10 - 296)
    613: *(u8 *)(r7 + 0) = r0
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    614: r0 = *(u64 *)(r10 - 320)
    615: *(u8 *)(r6 + 2) = r0
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    616: r0 = *(u64 *)(r10 - 328)
    617: *(u8 *)(r6 + 3) = r0
    ; ebpf_packetOffsetInBits += 32;
    618: r0 = r4
    619: r0 += 64
    620: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    621: r0 >>= 3
    622: r6 = r1
    623: r6 += r0
    624: r7 = *(u64 *)(r10 - 272)
    625: *(u8 *)(r6 + 0) = r7
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    626: r0 |= 1
    627: r7 = r1
    628: r7 += r0
    629: r0 = *(u64 *)(r10 - 280)
    630: *(u8 *)(r7 + 0) = r0
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    631: r0 = *(u64 *)(r10 - 304)
    632: *(u8 *)(r6 + 2) = r0
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    633: r0 = *(u64 *)(r10 - 312)
    634: *(u8 *)(r6 + 3) = r0
    ; ebpf_packetOffsetInBits += 32;
    635: r0 = r4
    636: r0 += 96
    637: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 4);
    638: r0 >>= 3
    639: r6 = r1
    640: r6 += r0
    641: r0 = *(u64 *)(r10 - 376)
    642: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 4;
    643: r0 = r4
    644: r0 += 100
    645: r0 &= r5
    ; write_partial(ebpf_packetStart + BYTES(ebpf_packetOffsetInBits) + 0, 4, (ebpf_byte) << 4);
    646: r0 >>= 3
    647: r6 = r1
    648: r6 += r0
    649: r0 = *(u8 *)(r6 + 0)
    650: r0 &= 240
    651: r7 = *(u64 *)(r10 - 368)
    652: r0 |= r7
    653: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 4;
    654: r0 = r4
    655: r0 += 104
    656: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    657: r0 >>= 3
    658: r6 = r1
    659: r6 += r0
    660: r0 = *(u64 *)(r10 - 360)
    661: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 8;
    662: r0 = r4
    663: r0 += 112
    664: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    665: r0 >>= 3
    666: r6 = r1
    667: r6 += r0
    668: r7 = *(u64 *)(r10 - 256)
    669: *(u8 *)(r6 + 0) = r7
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    670: r0 |= 1
    671: r6 = r1
    672: r6 += r0
    673: r0 = *(u64 *)(r10 - 264)
    674: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 16;
    675: r4 |= 128
    676: r0 = r4
    677: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    678: r0 >>= 3
    679: r6 = r1
    680: r6 += r0
    681: r7 = *(u64 *)(r10 - 240)
    682: *(u8 *)(r6 + 0) = r7
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    683: r0 |= 1
    684: r6 = r1
    685: r6 += r0
    686: r0 = *(u64 *)(r10 - 248)
    687: *(u8 *)(r6 + 0) = r0
    ; ebpf_packetOffsetInBits += 16;
    688: r0 = r4
    689: r0 += 16
    690: r0 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    691: r0 >>= 3
    692: r5 = r1
    693: r5 += r0
    694: r6 = *(u64 *)(r10 - 224)
    695: *(u8 *)(r5 + 0) = r6
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    696: r0 |= 1
    697: r5 = r1
    698: r5 += r0
    699: r0 = *(u64 *)(r10 - 232)
    700: *(u8 *)(r5 + 0) = r0
    ; ebpf_packetOffsetInBits += 16;
    701: r4 += 32

    LBB0_24:
    ; if (hd.icmp.ebpf_valid) {
    702: r5 = *(u64 *)(r10 - 80)
    703: if r5 == 0 goto 26
    ; if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 32)) {
    704: r0 = r4
    705: r0 += 32
    706: r5 = 4294967288ll
    708: r0 &= r5
    709: r0 >>= 3
    710: r6 = r1
    711: r6 += r0
    712: if r6 > r2 goto 17
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    713: r2 = r4
    714: r2 &= r5
    715: r2 >>= 3
    716: r0 = r1
    717: r0 += r2
    718: r2 = *(u64 *)(r10 - 520)
    719: *(u8 *)(r0 + 0) = r2
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    720: r2 = *(u64 *)(r10 - 392)
    721: *(u8 *)(r0 + 1) = r2
    ; ebpf_packetOffsetInBits += 16;
    722: r4 += 16
    723: r4 &= r5
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    724: r4 >>= 3
    725: r1 += r4
    726: r2 = *(u64 *)(r10 - 384)
    727: *(u8 *)(r1 + 0) = r2
    ; write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    728: r2 = *(u64 *)(r10 - 528)
    729: *(u8 *)(r1 + 1) = r2

    LBB0_27:
    730: r2 = r10
    731: r2 += -4
    732: r6 = 0
    ; bpf_map_update_elem(&ebpf_outTable, &ebpf_zero, &xout.output_port, BPF_ANY);
    733: r1 = 0ll
    735: r4 = 0
    736: call 2
    737: r7 = 2
    ; if (xout.drop) return XDP_DROP;
    738: r1 = *(u8 *)(r10 - 16)
    ; else return XDP_PASS;
    739: if r1 == r6 goto 3
    740: r7 = 1
    741: goto 1

    LBB0_30:
    742: r7 = 0

    LBB0_29:
    ; }
    743: r0 = r7
    744: exit
    588 changes: 588 additions & 0 deletions xdp7.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,588 @@
    #define KBUILD_MODNAME "xdptest"
    #include <linux/bpf.h>
    #include "bpf_helpers.h"

    #define load_byte(data, b) (*(u8 *)(data + (b)))
    #define load_half(data, b) __constant_ntohs(*(u16 *)(data + (b)))
    #define load_word(data, b) __constant_ntohl(*(u32 *)(data + (b)))
    #define htonl(d) __constant_htonl(d)
    #define htons(d) __constant_htons(d)
    enum ebpf_errorCodes {
    NoError,
    PacketTooShort,
    NoMatch,
    StackOutOfBounds,
    OverwritingHeader,
    HeaderTooShort,
    ParserTimeout,
    };

    #define EBPF_MASK(t, w) ((((t)(1)) << (w)) - (t)1)
    #define BYTES(w) ((w) / 8)
    #define write_partial(a, s, v) do { u8 mask = EBPF_MASK(u8, s); *((u8*)a) = ((*((u8*)a)) & ~mask) | (((v) >> (8 - (s))) & mask); } while (0)
    #define write_byte(base, offset, v) do { *(u8*)((base) + (offset)) = (v); } while (0)

    struct xdp_input {
    u32 input_port; /* bit<32> */
    };

    struct xdp_output {
    u8 drop; /* bool */
    u32 output_port; /* bit<32> */
    };

    struct Ethernet {
    char source[6]; /* bit<48> */
    char destination[6]; /* bit<48> */
    u16 protocol; /* bit<16> */
    u8 ebpf_valid;
    };

    struct IPv4 {
    u8 version; /* bit<4> */
    u8 ihl; /* bit<4> */
    u8 diffserv; /* bit<8> */
    u16 totalLen; /* bit<16> */
    u16 identification; /* bit<16> */
    u8 flags; /* bit<3> */
    u16 fragOffset; /* bit<13> */
    u8 ttl; /* bit<8> */
    u8 protocol; /* bit<8> */
    u16 hdrChecksum; /* bit<16> */
    u32 srcAddr; /* bit<32> */
    u32 dstAddr; /* bit<32> */
    u8 ebpf_valid;
    };

    struct icmp_t {
    u16 typeCode; /* bit<16> */
    u16 hdrChecksum; /* bit<16> */
    u8 ebpf_valid;
    };

    struct tcp_t {
    u16 srcPort; /* bit<16> */
    u16 dstPort; /* bit<16> */
    u32 seqNo; /* bit<32> */
    u32 ackNo; /* bit<32> */
    u8 dataOffset; /* bit<4> */
    u8 res; /* bit<4> */
    u8 flags; /* bit<8> */
    u16 window; /* bit<16> */
    u16 checksum; /* bit<16> */
    u16 urgentPtr; /* bit<16> */
    u8 ebpf_valid;
    };

    struct udp_t {
    u16 srcPort; /* bit<16> */
    u16 dstPort; /* bit<16> */
    u16 length_; /* bit<16> */
    u16 checksum; /* bit<16> */
    u8 ebpf_valid;
    };

    struct Headers {
    struct Ethernet ethernet; /* Ethernet */
    struct IPv4 ipv4; /* IPv4 */
    struct tcp_t tcp; /* tcp_t */
    struct udp_t udp; /* udp_t */
    struct icmp_t icmp; /* icmp_t */
    };

    struct dstmactable_key {
    u16 field0;
    };
    enum dstmactable_actions {
    Fallback_action,
    Drop_action,
    };
    struct dstmactable_value {
    enum dstmactable_actions action;
    union {
    struct {
    } Fallback_action;
    struct {
    } Drop_action;
    } u;
    };
    struct bpf_map_def SEC("maps") dstmactable = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(struct dstmactable_key),
    .value_size = sizeof(struct dstmactable_value),
    .pinning = 2, /* PIN_GLOBAL_NS */
    .max_entries = 64,
    };
    struct bpf_map_def SEC("maps") dstmactable_defaultAction = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(u32),
    .value_size = sizeof(struct dstmactable_value),
    .pinning = 2, /* PIN_GLOBAL_NS */
    .max_entries = 1,
    };
    struct bpf_map_def SEC("maps") ebpf_outTable = {
    .type = BPF_MAP_TYPE_PERCPU_ARRAY,
    .key_size = sizeof(u32),
    .value_size = sizeof(u32),
    .pinning = 2, /* PIN_GLOBAL_NS */
    .max_entries = 1 /* No multicast support */
    };

    SEC("prog")
    int ebpf_filter(struct xdp_md* skb){
    struct Headers hd = {
    .ethernet = {
    .ebpf_valid = 0
    },
    .ipv4 = {
    .ebpf_valid = 0
    },
    .tcp = {
    .ebpf_valid = 0
    },
    .udp = {
    .ebpf_valid = 0
    },
    .icmp = {
    .ebpf_valid = 0
    },
    };
    unsigned ebpf_packetOffsetInBits = 0;
    enum ebpf_errorCodes ebpf_errorCode = NoError;
    void* ebpf_packetStart = ((void*)(long)skb->data);
    void* ebpf_packetEnd = ((void*)(long)skb->data_end);
    u32 ebpf_zero = 0;
    u8 ebpf_byte = 0;
    u32 ebpf_outHeaderLength = 0;
    struct xdp_output xout;
    /* TODO: this should be initialized by the environment. HOW? */
    struct xdp_input xin;

    goto start;
    start: {
    /* extract(hd.ethernet)*/
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 112)) {
    ebpf_errorCode = PacketTooShort;
    goto reject;
    }
    hd.ethernet.source[0] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0) >> 0));
    hd.ethernet.source[1] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1) >> 0));
    hd.ethernet.source[2] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2) >> 0));
    hd.ethernet.source[3] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3) >> 0));
    hd.ethernet.source[4] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4) >> 0));
    hd.ethernet.source[5] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5) >> 0));
    ebpf_packetOffsetInBits += 48;

    hd.ethernet.destination[0] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0) >> 0));
    hd.ethernet.destination[1] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1) >> 0));
    hd.ethernet.destination[2] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2) >> 0));
    hd.ethernet.destination[3] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3) >> 0));
    hd.ethernet.destination[4] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4) >> 0));
    hd.ethernet.destination[5] = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5) >> 0));
    ebpf_packetOffsetInBits += 48;

    hd.ethernet.protocol = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.ethernet.ebpf_valid = 1;

    switch (hd.ethernet.protocol) {
    case 2048: goto parse_ipv4;
    default: goto accept;
    }
    }
    parse_ipv4: {
    /* extract(hd.ipv4)*/
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    ebpf_errorCode = PacketTooShort;
    goto reject;
    }
    hd.ipv4.version = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4));
    ebpf_packetOffsetInBits += 4;

    hd.ipv4.ihl = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4));
    ebpf_packetOffsetInBits += 4;

    hd.ipv4.diffserv = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 8;

    hd.ipv4.totalLen = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.ipv4.identification = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.ipv4.flags = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3));
    ebpf_packetOffsetInBits += 3;

    hd.ipv4.fragOffset = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13));
    ebpf_packetOffsetInBits += 13;

    hd.ipv4.ttl = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 8;

    hd.ipv4.protocol = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 8;

    hd.ipv4.hdrChecksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.ipv4.srcAddr = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 32;

    hd.ipv4.dstAddr = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 32;

    hd.ipv4.ebpf_valid = 1;

    switch (hd.ipv4.protocol) {
    case 6: goto parse_tcp;
    case 17: goto parse_udp;
    case 1: goto parse_icmp;
    default: goto accept;
    }
    }
    parse_icmp: {
    /* extract(hd.icmp)*/
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 32)) {
    ebpf_errorCode = PacketTooShort;
    goto reject;
    }
    hd.icmp.typeCode = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.icmp.hdrChecksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.icmp.ebpf_valid = 1;

    goto accept;
    }
    parse_tcp: {
    /* extract(hd.tcp)*/
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    ebpf_errorCode = PacketTooShort;
    goto reject;
    }
    hd.tcp.srcPort = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.tcp.dstPort = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.tcp.seqNo = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 32;

    hd.tcp.ackNo = (u32)((load_word(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 32;

    hd.tcp.dataOffset = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4));
    ebpf_packetOffsetInBits += 4;

    hd.tcp.res = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4));
    ebpf_packetOffsetInBits += 4;

    hd.tcp.flags = (u8)((load_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 8;

    hd.tcp.window = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.tcp.checksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.tcp.urgentPtr = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.tcp.ebpf_valid = 1;

    goto accept;
    }
    parse_udp: {
    /* extract(hd.udp)*/
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 64)) {
    ebpf_errorCode = PacketTooShort;
    goto reject;
    }
    hd.udp.srcPort = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.udp.dstPort = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.udp.length_ = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.udp.checksum = (u16)((load_half(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits))));
    ebpf_packetOffsetInBits += 16;

    hd.udp.ebpf_valid = 1;

    goto accept;
    }

    reject: { return XDP_ABORTED; }

    accept:
    {
    u8 hit;
    u8 xoutdrop;
    {
    /* dstmactable.apply()*/
    {
    /* construct key */
    struct dstmactable_key key;
    key.field0 = hd.ethernet.protocol;
    /* value */
    struct dstmactable_value *value;
    /* perform lookup */
    value = bpf_map_lookup_elem(&dstmactable, &key);
    if (value == NULL) {
    /* miss; find default action */
    hit = 0;
    value = bpf_map_lookup_elem(&dstmactable_defaultAction, &ebpf_zero);
    } else {
    hit = 1;
    }
    if (value != NULL) {
    /* run action */
    switch (value->action) {
    case Fallback_action:
    {
    hd.ipv4.ttl = 4;
    xoutdrop = false;
    }
    break;
    case Drop_action:
    {
    xoutdrop = true;
    }
    break;
    default: return XDP_ABORTED;
    }
    }
    else return XDP_ABORTED;
    }
    ;
    xout.output_port = 0;
    xout.drop = xoutdrop;
    }
    }
    /* deparser */
    {
    {
    if (hd.ethernet.ebpf_valid) ebpf_outHeaderLength += 112;
    if (hd.ipv4.ebpf_valid) ebpf_outHeaderLength += 160;
    if (hd.tcp.ebpf_valid) ebpf_outHeaderLength += 160;
    if (hd.icmp.ebpf_valid) ebpf_outHeaderLength += 32;
    }
    // bpf_xdp_adjust_head(skb, BYTES(ebpf_packetOffsetInBits) - ebpf_outHeaderLength);
    ebpf_packetStart = ((void*)(long)skb->data);
    ebpf_packetEnd = ((void*)(long)skb->data_end);
    ebpf_packetOffsetInBits = 0;
    u8 hit_0;
    {
    /* packet.emit(hd.ethernet)*/
    if (hd.ethernet.ebpf_valid) {
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 112)) {
    ebpf_errorCode = PacketTooShort;
    goto ebpf_end;
    }
    ebpf_byte = ((char*)(&hd.ethernet.source))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.source))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.source))[2];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.source))[3];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.source))[4];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.source))[5];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 48;
    ebpf_byte = ((char*)(&hd.ethernet.destination))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.destination))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.destination))[2];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.destination))[3];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.destination))[4];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.destination))[5];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 48;
    hd.ethernet.protocol = htons(hd.ethernet.protocol);
    ebpf_byte = ((char*)(&hd.ethernet.protocol))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ethernet.protocol))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    }
    ;
    /* packet.emit(hd.ipv4)*/
    if (hd.ipv4.ebpf_valid) {
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    ebpf_errorCode = PacketTooShort;
    goto ebpf_end;
    }
    ebpf_byte = ((char*)(&hd.ipv4.version))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 4);
    ebpf_packetOffsetInBits += 4;
    ebpf_byte = ((char*)(&hd.ipv4.ihl))[0];
    write_partial(ebpf_packetStart + BYTES(ebpf_packetOffsetInBits) + 0, 4, (ebpf_byte) << 4);
    ebpf_packetOffsetInBits += 4;
    ebpf_byte = ((char*)(&hd.ipv4.diffserv))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 8;
    hd.ipv4.totalLen = htons(hd.ipv4.totalLen);
    ebpf_byte = ((char*)(&hd.ipv4.totalLen))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.totalLen))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.ipv4.identification = htons(hd.ipv4.identification);
    ebpf_byte = ((char*)(&hd.ipv4.identification))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.identification))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    ebpf_byte = ((char*)(&hd.ipv4.flags))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 5);
    ebpf_packetOffsetInBits += 3;
    ebpf_byte = ((char*)(&hd.ipv4.fragOffset))[0];
    write_partial(ebpf_packetStart + BYTES(ebpf_packetOffsetInBits) + 0, 3, (ebpf_byte) << 3);
    ebpf_byte = ((char*)(&hd.ipv4.fragOffset))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 13;
    ebpf_byte = ((char*)(&hd.ipv4.ttl))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 8;
    ebpf_byte = ((char*)(&hd.ipv4.protocol))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 8;
    hd.ipv4.hdrChecksum = htons(hd.ipv4.hdrChecksum);
    ebpf_byte = ((char*)(&hd.ipv4.hdrChecksum))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.hdrChecksum))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.ipv4.srcAddr = htonl(hd.ipv4.srcAddr);
    ebpf_byte = ((char*)(&hd.ipv4.srcAddr))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.srcAddr))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.srcAddr))[2];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.srcAddr))[3];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 32;
    hd.ipv4.dstAddr = htonl(hd.ipv4.dstAddr);
    ebpf_byte = ((char*)(&hd.ipv4.dstAddr))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.dstAddr))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.dstAddr))[2];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.ipv4.dstAddr))[3];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 32;
    }
    ;
    /* packet.emit(hd.tcp)*/
    if (hd.tcp.ebpf_valid) {
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 160)) {
    ebpf_errorCode = PacketTooShort;
    goto ebpf_end;
    }
    hd.tcp.srcPort = htons(hd.tcp.srcPort);
    ebpf_byte = ((char*)(&hd.tcp.srcPort))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.srcPort))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.tcp.dstPort = htons(hd.tcp.dstPort);
    ebpf_byte = ((char*)(&hd.tcp.dstPort))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.dstPort))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.tcp.seqNo = htonl(hd.tcp.seqNo);
    ebpf_byte = ((char*)(&hd.tcp.seqNo))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.seqNo))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.seqNo))[2];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.seqNo))[3];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 32;
    hd.tcp.ackNo = htonl(hd.tcp.ackNo);
    ebpf_byte = ((char*)(&hd.tcp.ackNo))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.ackNo))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.ackNo))[2];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.ackNo))[3];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 32;
    ebpf_byte = ((char*)(&hd.tcp.dataOffset))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 4);
    ebpf_packetOffsetInBits += 4;
    ebpf_byte = ((char*)(&hd.tcp.res))[0];
    write_partial(ebpf_packetStart + BYTES(ebpf_packetOffsetInBits) + 0, 4, (ebpf_byte) << 4);
    ebpf_packetOffsetInBits += 4;
    ebpf_byte = ((char*)(&hd.tcp.flags))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 8;
    hd.tcp.window = htons(hd.tcp.window);
    ebpf_byte = ((char*)(&hd.tcp.window))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.window))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.tcp.checksum = htons(hd.tcp.checksum);
    ebpf_byte = ((char*)(&hd.tcp.checksum))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.checksum))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.tcp.urgentPtr = htons(hd.tcp.urgentPtr);
    ebpf_byte = ((char*)(&hd.tcp.urgentPtr))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.tcp.urgentPtr))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    }
    ;
    /* packet.emit(hd.icmp)*/
    if (hd.icmp.ebpf_valid) {
    if (ebpf_packetEnd < ebpf_packetStart + BYTES(ebpf_packetOffsetInBits + 32)) {
    ebpf_errorCode = PacketTooShort;
    goto ebpf_end;
    }
    hd.icmp.typeCode = htons(hd.icmp.typeCode);
    ebpf_byte = ((char*)(&hd.icmp.typeCode))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.icmp.typeCode))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    hd.icmp.hdrChecksum = htons(hd.icmp.hdrChecksum);
    ebpf_byte = ((char*)(&hd.icmp.hdrChecksum))[0];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte) << 0);
    ebpf_byte = ((char*)(&hd.icmp.hdrChecksum))[1];
    write_byte(ebpf_packetStart, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte) << 0);
    ebpf_packetOffsetInBits += 16;
    }
    ;
    }
    }
    ebpf_end:
    bpf_map_update_elem(&ebpf_outTable, &ebpf_zero, &xout.output_port, BPF_ANY);
    if (xout.drop) return XDP_DROP;
    else return XDP_PASS;
    }
    char _license[] SEC("license") = "GPL";