.arg1_type = ARG_PTR_TO_CTX,
};
-static void bpf_skb_change_protocol(struct sk_buff *skb, u16 proto)
-{
- skb->protocol = htons(proto);
- if (skb_valid_dst(skb))
- skb_dst_drop(skb);
-}
-
static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
{
/* Caller already did skb_cow() with meta_len+len as headroom,
shinfo->gso_type |= SKB_GSO_DODGY;
}
- bpf_skb_change_protocol(skb, ETH_P_IPV6);
+ skb->protocol = htons(ETH_P_IPV6);
skb_clear_hash(skb);
return 0;
shinfo->gso_type |= SKB_GSO_DODGY;
}
- bpf_skb_change_protocol(skb, ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
skb_clear_hash(skb);
return 0;
*/
ret = bpf_skb_proto_xlat(skb, proto);
bpf_compute_data_pointers(skb);
- return ret;
+ if (ret)
+ return ret;
+
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
+
+ return 0;
}
static const struct bpf_func_proto bpf_skb_change_proto_proto = {
}
/* Match skb->protocol to new outer l3 protocol */
- if (skb->protocol == htons(ETH_P_IP) &&
- flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6)
- bpf_skb_change_protocol(skb, ETH_P_IPV6);
- else if (skb->protocol == htons(ETH_P_IPV6) &&
- flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4)
- bpf_skb_change_protocol(skb, ETH_P_IP);
+ if (flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6)
+ skb->protocol = htons(ETH_P_IPV6);
+ else if (flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4)
+ skb->protocol = htons(ETH_P_IP);
+
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
}
if (skb_is_gso(skb)) {
static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
u64 flags)
{
+ bool decap = flags & BPF_F_ADJ_ROOM_DECAP_L3_MASK;
int ret;
if (unlikely(flags & ~(BPF_F_ADJ_ROOM_FIXED_GSO |
if (unlikely(ret < 0))
return ret;
- /* Match skb->protocol to new outer l3 protocol */
- if (skb->protocol == htons(ETH_P_IP) &&
- flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6)
- bpf_skb_change_protocol(skb, ETH_P_IPV6);
- else if (skb->protocol == htons(ETH_P_IPV6) &&
- flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4)
- bpf_skb_change_protocol(skb, ETH_P_IP);
+ if (decap) {
+ /* Match skb->protocol to new outer l3 protocol */
+ if (flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6)
+ skb->protocol = htons(ETH_P_IPV6);
+ else if (flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4)
+ skb->protocol = htons(ETH_P_IP);
+
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
+ }
if (skb_is_gso(skb)) {
struct skb_shared_info *shinfo = skb_shinfo(skb);