*             Grow or shrink the room for data in the packet associated to
  *             *skb* by *len_diff*, and according to the selected *mode*.
  *
- *             There is a single supported mode at this time:
+ *             There are two supported modes at this time:
+ *
+ *             * **BPF_ADJ_ROOM_MAC**: Adjust room at the mac layer
+ *               (room space is added or removed below the layer 2 header).
  *
  *             * **BPF_ADJ_ROOM_NET**: Adjust room at the network layer
  *               (room space is added or removed below the layer 3 header).
 /* Mode for BPF_FUNC_skb_adjust_room helper. */
 enum bpf_adj_room_mode {
        BPF_ADJ_ROOM_NET,
+       BPF_ADJ_ROOM_MAC,
 };
 
 /* Mode for BPF_FUNC_skb_load_bytes_relative helper. */
 
        }
 }
 
-static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff)
+static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff)
 {
-       u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
        int ret;
 
        if (skb_is_gso(skb) && !skb_is_gso_tcp(skb))
        return 0;
 }
 
-static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff)
+static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff)
 {
-       u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
        int ret;
 
        if (skb_is_gso(skb) && !skb_is_gso_tcp(skb))
                          SKB_MAX_ALLOC;
 }
 
-static int bpf_skb_adjust_net(struct sk_buff *skb, s32 len_diff)
+BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
+          u32, mode, u64, flags)
 {
        bool trans_same = skb->transport_header == skb->network_header;
        u32 len_cur, len_diff_abs = abs(len_diff);
        u32 len_max = __bpf_skb_max_len(skb);
        __be16 proto = skb->protocol;
        bool shrink = len_diff < 0;
+       u32 off;
        int ret;
 
+       if (unlikely(flags))
+               return -EINVAL;
        if (unlikely(len_diff_abs > 0xfffU))
                return -EFAULT;
        if (unlikely(proto != htons(ETH_P_IP) &&
                     proto != htons(ETH_P_IPV6)))
                return -ENOTSUPP;
 
+       off = skb_mac_header_len(skb);
+       switch (mode) {
+       case BPF_ADJ_ROOM_NET:
+               off += bpf_skb_net_base_len(skb);
+               break;
+       case BPF_ADJ_ROOM_MAC:
+               break;
+       default:
+               return -ENOTSUPP;
+       }
+
        len_cur = skb->len - skb_network_offset(skb);
        if (skb_transport_header_was_set(skb) && !trans_same)
                len_cur = skb_network_header_len(skb);
                         !skb_is_gso(skb))))
                return -ENOTSUPP;
 
-       ret = shrink ? bpf_skb_net_shrink(skb, len_diff_abs) :
-                      bpf_skb_net_grow(skb, len_diff_abs);
+       ret = shrink ? bpf_skb_net_shrink(skb, off, len_diff_abs) :
+                      bpf_skb_net_grow(skb, off, len_diff_abs);
 
        bpf_compute_data_pointers(skb);
        return ret;
 }
 
-BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
-          u32, mode, u64, flags)
-{
-       if (unlikely(flags))
-               return -EINVAL;
-       if (likely(mode == BPF_ADJ_ROOM_NET))
-               return bpf_skb_adjust_net(skb, len_diff);
-
-       return -ENOTSUPP;
-}
-
 static const struct bpf_func_proto bpf_skb_adjust_room_proto = {
        .func           = bpf_skb_adjust_room,
        .gpl_only       = false,