Drop PROTO macro syntax and introduce alternative

* Feedback given by some external users was that the PROTO syntax was
  opaque and unintuitive. As such, drop that macro and introduce an
  alternative syntax.
* Convert all to use 'cursor_advance' macro API

Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
diff --git a/examples/tc_neighbor_sharing.c b/examples/tc_neighbor_sharing.c
index 87ea0ea..8d1c3bf 100644
--- a/examples/tc_neighbor_sharing.c
+++ b/examples/tc_neighbor_sharing.c
@@ -19,14 +19,16 @@
 // returns: > 0 when an IP is known
 //          = 0 when an IP is not known, or non-IP traffic
 int classify_wan(struct __sk_buff *skb) {
-  BEGIN(ethernet);
-  PROTO(ethernet) {
+  u8 *cursor = 0;
+  ethernet: {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     switch (ethernet->type) {
-      case 0x0800: goto ip;
+      case ETH_P_IP: goto ip;
+      default: goto EOP;
     }
-    goto EOP;
   }
-  PROTO(ip) {
+  ip: {
+    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
     u32 dip = ip->dst;
     struct ipkey key = {.client_ip=dip};
     int *val = learned_ips.lookup(&key);
@@ -42,14 +44,16 @@
 // Mark the inserted entry with a non-zero value to be used by the classify_wan
 // lookup.
 int classify_neighbor(struct __sk_buff *skb) {
-  BEGIN(ethernet);
-  PROTO(ethernet) {
+  u8 *cursor = 0;
+  ethernet: {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     switch (ethernet->type) {
-      case 0x0800: goto ip;
+      case ETH_P_IP: goto ip;
+      default: goto EOP;
     }
-    goto EOP;
   }
-  PROTO(ip) {
+  ip: {
+    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
     u32 sip = ip->src;
     struct ipkey key = {.client_ip=sip};
     int val = 1;
diff --git a/examples/tunnel_monitor/monitor.c b/examples/tunnel_monitor/monitor.c
index 6401f3f..8b17078 100644
--- a/examples/tunnel_monitor/monitor.c
+++ b/examples/tunnel_monitor/monitor.c
@@ -57,37 +57,43 @@
 
 // parse the outer vxlan frame
 int handle_outer(struct __sk_buff *skb) {
-  BEGIN(ethernet);
-  PROTO(ethernet) {
-    // filter bcast/mcast from the stats
-    if (ethernet->dst & (1ull << 40))
-      return 1;
-    switch (ethernet->type) {
-      case 0x0800: goto ip;
-    }
-    goto EOP;
+  u8 *skb_cursor = 0;
+
+  struct ethernet_t *ethernet = bpf_consume_skb(skb_cursor, sizeof(*ethernet));
+
+  // filter bcast/mcast from the stats
+  if (ethernet->dst & (1ull << 40))
+    goto finish;
+
+  switch (ethernet->type) {
+    case 0x0800: goto ip;
+    default: goto finish;
   }
-  PROTO(ip) {
-    skb->cb[CB_SIP] = ip->src;
-    skb->cb[CB_DIP] = ip->dst;
-    switch (ip->nextp) {
-      case 17: goto udp;
-    }
-    goto EOP;
+
+ip: ;
+  struct ip_t *ip = bpf_consume_skb(skb_cursor, sizeof(*ip));
+  skb->cb[CB_SIP] = ip->src;
+  skb->cb[CB_DIP] = ip->dst;
+
+  switch (ip->nextp) {
+    case 17: goto udp;
+    default: goto finish;
   }
-  PROTO(udp) {
-    switch (udp->dport) {
-      case 4789: goto vxlan;
-    }
-    goto EOP;
+
+udp: ;
+  struct udp_t *udp = bpf_consume_skb(skb_cursor, sizeof(*udp));
+  switch (udp->dport) {
+    case 4789: goto vxlan;
+    default: goto finish;
   }
-  PROTO(vxlan) {
-    skb->cb[CB_VNI] = vxlan->key;
-    skb->cb[CB_OFFSET] = (u64)vxlan + sizeof(*vxlan);
-    parser.call(skb, 2);
-    goto EOP;
-  }
-EOP:
+
+vxlan: ;
+  struct vxlan_t *vxlan = bpf_consume_skb(skb_cursor, sizeof(*vxlan));
+  skb->cb[CB_VNI] = vxlan->key;
+  skb->cb[CB_OFFSET] = (u64)vxlan + sizeof(*vxlan);
+  parser.call(skb, 2);
+
+finish:
   return 1;
 }
 
@@ -100,19 +106,19 @@
     .outer_sip = skb->cb[CB_SIP],
     .outer_dip = skb->cb[CB_DIP]
   };
-  BEGIN_OFFSET(ethernet, skb->cb[CB_OFFSET]);
-  PROTO(ethernet) {
-    switch (ethernet->type) {
-      case 0x0800: goto ip;
-    }
-    goto EOP;
+  u8 *skb_cursor = (u8 *)(u64)skb->cb[CB_OFFSET];
+
+  struct ethernet_t *ethernet = bpf_consume_skb(skb_cursor, sizeof(*ethernet));
+  switch (ethernet->type) {
+    case 0x0800: goto ip;
+    default: goto finish;
   }
-  PROTO(ip) {
-    key.inner_sip = ip->src;
-    key.inner_dip = ip->dst;
-    goto EOP;
-  }
-EOP:
+ip: ;
+  struct ip_t *ip = bpf_consume_skb(skb_cursor, sizeof(*ip));
+  key.inner_sip = ip->src;
+  key.inner_dip = ip->dst;
+
+finish:
   // consistent ordering
   if (key.outer_dip < key.outer_sip)
     swap_ipkey(&key);
diff --git a/examples/vlan_learning.c b/examples/vlan_learning.c
index ae77a8b..74115df 100644
--- a/examples/vlan_learning.c
+++ b/examples/vlan_learning.c
@@ -16,8 +16,9 @@
 BPF_TABLE("hash", u64, struct ifindex_leaf_t, ingress, 4096);
 
 int handle_phys2virt(struct __sk_buff *skb) {
-  BEGIN(ethernet);
-  PROTO(ethernet) {
+  u8 *cursor = 0;
+  ethernet: {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     u64 src_mac = ethernet->src;
     struct ifindex_leaf_t *leaf = ingress.lookup(&src_mac);
     if (leaf) {
@@ -33,13 +34,13 @@
       bpf_clone_redirect(skb, leaf->out_ifindex, 0);
     }
   }
-EOP:
   return 1;
 }
 
 int handle_virt2phys(struct __sk_buff *skb) {
-  BEGIN(ethernet);
-  PROTO(ethernet) {
+  u8 *cursor = 0;
+  ethernet: {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     int src_ifindex = skb->ifindex;
     struct ifindex_leaf_t *leaf = egress.lookup(&src_ifindex);
     if (leaf) {
@@ -48,6 +49,5 @@
       bpf_clone_redirect(skb, leaf->out_ifindex, 0);
     }
   }
-EOP:
   return 1;
 }
diff --git a/src/cc/b_frontend_action.cc b/src/cc/b_frontend_action.cc
index f7d085e..f3180b8 100644
--- a/src/cc/b_frontend_action.cc
+++ b/src/cc/b_frontend_action.cc
@@ -381,6 +381,18 @@
       return false;
     }
     tables_[Decl->getName()] = std::move(table);
+  } else if (const PointerType *P = Decl->getType()->getAs<PointerType>()) {
+    // if var is a pointer to a packet type, clone the annotation into the var
+    // decl so that the packet dext/dins rewriter can catch it
+    if (const RecordType *RT = P->getPointeeType()->getAs<RecordType>()) {
+      if (const RecordDecl *RD = RT->getDecl()->getDefinition()) {
+        if (DeprecatedAttr *DA = RD->getAttr<DeprecatedAttr>()) {
+          if (DA->getMessage() == "packet") {
+            Decl->addAttr(DA->clone(C));
+          }
+        }
+      }
+    }
   }
   return true;
 }
diff --git a/src/cc/export/helpers.h b/src/cc/export/helpers.h
index 960998f..e5c8bc4 100644
--- a/src/cc/export/helpers.h
+++ b/src/cc/export/helpers.h
@@ -42,18 +42,8 @@
 struct _name##_table_t _name
 
 // packet parsing state machine helpers
-#define BEGIN(next) \
-  u64 _parse_cursor = 0; \
-  goto next
-#define BEGIN_OFFSET(next, _base_offset) \
-  u64 _parse_cursor = (_base_offset); \
-  goto next
-
-#define PROTO(name) \
-  goto EOP; \
-name: ; \
-  struct name##_t *name __attribute__((deprecated("packet"))) = (void *)_parse_cursor; \
-  _parse_cursor += sizeof(*name);
+#define cursor_advance(_cursor, _len) \
+  ({ void *_tmp = _cursor; _cursor += _len; _tmp; })
 
 char _license[4] SEC("license") = "GPL";
 
diff --git a/src/cc/export/proto.h b/src/cc/export/proto.h
index 408b64b..a7fe460 100644
--- a/src/cc/export/proto.h
+++ b/src/cc/export/proto.h
@@ -14,18 +14,22 @@
  * limitations under the License.
  */
 
+#include <uapi/linux/if_ether.h>
+
+#define BPF_PACKET_HEADER __attribute__((packed)) __attribute__((deprecated("packet")))
+
 struct ethernet_t {
   unsigned long long  dst:48;
   unsigned long long  src:48;
   unsigned int        type:16;
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
 
 struct dot1q_t {
   unsigned short pri:3;
   unsigned short cfi:1;
   unsigned short vlanid:12;
   unsigned short type;
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
 
 struct arp_t {
   unsigned short      htype;
@@ -37,7 +41,7 @@
   unsigned long long  spa:32;
   unsigned long long  tha:48;
   unsigned int        tpa;
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
 
 struct ip_t {
   unsigned char   ver:4;           // byte 0
@@ -54,14 +58,14 @@
   unsigned short  hchecksum;
   unsigned int    src;            // byte 12
   unsigned int    dst;            // byte 16
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
 
 struct udp_t {
   unsigned short sport;
   unsigned short dport;
   unsigned short length;
   unsigned short crc;
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
 
 struct tcp_t {
   unsigned short  src_port;   // byte 0
@@ -81,7 +85,7 @@
   unsigned short  rcv_wnd;
   unsigned short  cksum;      // byte 16
   unsigned short  urg_ptr;
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
 
 struct vxlan_t {
   unsigned int rsv1:4;
@@ -90,4 +94,4 @@
   unsigned int rsv3:24;
   unsigned int key:24;
   unsigned int rsv4:8;
-} __attribute__((packed));
+} BPF_PACKET_HEADER;
diff --git a/tests/cc/test_brb.c b/tests/cc/test_brb.c
index fde7b04..b32e8c1 100644
--- a/tests/cc/test_brb.c
+++ b/tests/cc/test_brb.c
@@ -106,6 +106,7 @@
 
 static int br_common(struct __sk_buff *skb, int which_br) __attribute__((always_inline));
 static int br_common(struct __sk_buff *skb, int which_br) {
+    u8 *cursor = 0;
     bpf_metadata_t meta = {};
     u16 proto;
     u16 arpop;
@@ -126,8 +127,8 @@
         meta.rx_port_id = skb->cb[1];
     }
 
-    BEGIN(ethernet);
-    PROTO(ethernet) {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
+    {
         dmac.addr = ethernet->dst;
         if (meta.prog_id != 0) {
             /* send to the router */
@@ -152,22 +153,24 @@
         }
 
         switch (ethernet->type) {
-            case 0x0800: goto ip;
-            case 0x0806: goto arp;
-            case 0x8100: goto dot1q;
+            case ETH_P_IP: goto ip;
+            case ETH_P_ARP: goto arp;
+            case ETH_P_8021Q: goto dot1q;
+            default: goto EOP;
         }
-        goto EOP;
     }
 
-    PROTO(dot1q) {
+    dot1q: {
+        struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
         switch(dot1q->type) {
-            case 0x0806: goto arp;
-            case 0x0800: goto ip;
+            case ETH_P_IP: goto ip;
+            case ETH_P_ARP: goto arp;
+            default: goto EOP;
         }
-        goto EOP;
     }
 
-    PROTO(arp) {
+    arp: {
+        struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
         /* mac learning */
         arpop = arp->oper;
         if (arpop == 2) {
@@ -180,7 +183,7 @@
                 __u32 ifindex = *rtrif_p;
                 eth_addr_t smac;
 
-		smac.addr = ethernet->src;
+                smac.addr = ethernet->src;
                 if (which_br == 1)
                     br1_mac_ifindex.update(&smac, &ifindex);
                 else
@@ -190,7 +193,8 @@
         goto xmit;
     }
 
-    PROTO(ip) {
+    ip: {
+        struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
         goto xmit;
     }
 
diff --git a/tests/cc/test_clang.py b/tests/cc/test_clang.py
index d5ff625..9d92be8 100755
--- a/tests/cc/test_clang.py
+++ b/tests/cc/test_clang.py
@@ -13,12 +13,10 @@
         text = """
 #include <bcc/proto.h>
 int handle_packet(void *ctx) {
-  BEGIN(ethernet);
-  PROTO(ethernet) {
-    bpf_trace_printk("ethernet->dst = %llx, ethernet->src = %llx\\n",
-                     ethernet->dst, ethernet->src);
-  }
-EOP:
+  u8 *cursor = 0;
+  struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
+  bpf_trace_printk("ethernet->dst = %llx, ethernet->src = %llx\\n",
+                   ethernet->dst, ethernet->src);
   return 0;
 }
 """
diff --git a/tests/cc/test_clang_complex.c b/tests/cc/test_clang_complex.c
index fd7f93f..ed1f231 100644
--- a/tests/cc/test_clang_complex.c
+++ b/tests/cc/test_clang_complex.c
@@ -42,6 +42,7 @@
 
 int handle_packet(struct __sk_buff *skb) {
   int ret = 0;
+  u8 *cursor = 0;
 
   if (skb->pkt_type == 0) {
     // tx
@@ -70,26 +71,25 @@
     ret = 0;
   }
 
-  BEGIN(ethernet);
-
-  PROTO(ethernet) {
-    switch (ethernet->type) {
-      case 0x0806: goto arp;
-      case 0x0800: goto ip;
-      case 0x8100: goto dot1q;
-    }
-    goto EOP;
+  struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
+  switch (ethernet->type) {
+    case ETH_P_IP: goto ip;
+    case ETH_P_ARP: goto arp;
+    case ETH_P_8021Q: goto dot1q;
+    default: goto EOP;
   }
 
-  PROTO(dot1q) {
+  dot1q: {
+    struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
     switch (dot1q->type) {
-      case 0x0806: goto arp;
-      case 0x0800: goto ip;
+      case ETH_P_IP: goto ip;
+      case ETH_P_ARP: goto arp;
+      default: goto EOP;
     }
-    goto EOP;
   }
 
-  PROTO(arp) {
+  arp: {
+    struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
     if (skb->pkt_type) {
       if (arp->oper == 1) {
         struct MacaddrKey mac_key = {.ip=arp->spa};
@@ -100,17 +100,20 @@
     goto EOP;
   }
 
-  PROTO(ip) {
+  struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
+  ip: {
     switch (ip->nextp) {
       case 6: goto tcp;
       case 17: goto udp;
+      default: goto EOP;
     }
+  }
+  tcp: {
+    struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
     goto EOP;
   }
-  PROTO(tcp) {
-    goto EOP;
-  }
-  PROTO(udp) {
+  udp: {
+    struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
     if (udp->dport != 5000) {
        goto EOP;
     }
diff --git a/tests/cc/test_stat1.c b/tests/cc/test_stat1.c
index 61c11c2..d7030c0 100644
--- a/tests/cc/test_stat1.c
+++ b/tests/cc/test_stat1.c
@@ -15,20 +15,26 @@
 BPF_TABLE("hash", struct IPKey, struct IPLeaf, stats, 256);
 
 int on_packet(struct __sk_buff *skb) {
-  BEGIN(ethernet);
-
-  PROTO(ethernet) {
+  u8 *cursor = 0;
+  ethernet: {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     switch (ethernet->type) {
-      case 0x0800: goto ip;
-      case 0x8100: goto dot1q;
+        case ETH_P_IP: goto ip;
+        case ETH_P_8021Q: goto dot1q;
+        default: goto EOP;
     }
   }
-  PROTO(dot1q) {
+
+  dot1q: {
+    struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
     switch (dot1q->type) {
-      case 0x0800: goto ip;
+      case ETH_P_8021Q: goto ip;
+      default: goto EOP;
     }
   }
-  PROTO(ip) {
+
+  ip: {
+    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
     int rx = 0, tx = 0;
     struct IPKey key;
     if (ip->dst > ip->src) {
@@ -45,6 +51,7 @@
     lock_xadd(&leaf->rx_pkts, rx);
     lock_xadd(&leaf->tx_pkts, tx);
   }
+
 EOP:
   return 0;
 }
diff --git a/tests/cc/test_xlate1.c b/tests/cc/test_xlate1.c
index eb96878..2a0c68b 100644
--- a/tests/cc/test_xlate1.c
+++ b/tests/cc/test_xlate1.c
@@ -14,29 +14,33 @@
 BPF_TABLE("hash", struct IPKey, struct IPLeaf, xlate, 1024);
 
 int on_packet(struct __sk_buff *skb) {
+  u8 *cursor = 0;
 
   u32 orig_dip = 0;
   u32 orig_sip = 0;
   struct IPLeaf *xleaf;
 
-  BEGIN(ethernet);
-  PROTO(ethernet) {
+  ethernet: {
+    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     switch (ethernet->type) {
-      case 0x0800: goto ip;
-      case 0x0806: goto arp;
-      case 0x8100: goto dot1q;
+      case ETH_P_IP: goto ip;
+      case ETH_P_ARP: goto arp;
+      case ETH_P_8021Q: goto dot1q;
+      default: goto EOP;
     }
-    goto EOP;
   }
 
-  PROTO(dot1q) {
+  dot1q: {
+    struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
     switch (dot1q->type) {
-      case 0x0806: goto arp;
-      case 0x0800: goto ip;
+      case ETH_P_IP: goto ip;
+      case ETH_P_ARP: goto arp;
+      default: goto EOP;
     }
-    goto EOP;
   }
-  PROTO(arp) {
+
+  arp: {
+    struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
     orig_dip = arp->tpa;
     orig_sip = arp->spa;
     struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
@@ -49,7 +53,8 @@
     goto EOP;
   }
 
-  PROTO(ip) {
+  ip: {
+    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
     orig_dip = ip->dst;
     orig_sip = ip->src;
     struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
@@ -64,11 +69,12 @@
     switch (ip->nextp) {
       case 6: goto tcp;
       case 17: goto udp;
+      default: goto EOP;
     }
-    goto EOP;
   }
 
-  PROTO(udp) {
+  udp: {
+    struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
     if (xleaf) {
       incr_cksum_l4(&udp->crc, orig_dip, xleaf->xdip, 1);
       incr_cksum_l4(&udp->crc, orig_sip, xleaf->xsip, 1);
@@ -76,7 +82,8 @@
     goto EOP;
   }
 
-  PROTO(tcp) {
+  tcp: {
+    struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
     if (xleaf) {
       incr_cksum_l4(&tcp->cksum, orig_dip, xleaf->xdip, 1);
       incr_cksum_l4(&tcp->cksum, orig_sip, xleaf->xsip, 1);