github.com/cilium/cilium@v1.16.2/bpf/lib/eth.h (about) 1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 /* Copyright Authors of Cilium */ 3 4 #pragma once 5 6 #include <linux/if_ether.h> 7 8 #ifndef ETH_HLEN 9 #define ETH_HLEN __ETH_HLEN 10 #endif 11 12 #ifndef ETH_ALEN 13 #define ETH_ALEN 6 14 #endif 15 16 union macaddr { 17 struct { 18 __u32 p1; 19 __u16 p2; 20 }; 21 __u8 addr[6]; 22 }; 23 24 static __always_inline int eth_addrcmp(const union macaddr *a, 25 const union macaddr *b) 26 { 27 int tmp; 28 29 tmp = a->p1 - b->p1; 30 if (!tmp) 31 tmp = a->p2 - b->p2; 32 33 return tmp; 34 } 35 36 static __always_inline int eth_is_bcast(const union macaddr *a) 37 { 38 union macaddr bcast; 39 40 bcast.p1 = 0xffffffff; 41 bcast.p2 = 0xffff; 42 43 if (!eth_addrcmp(a, &bcast)) 44 return 1; 45 else 46 return 0; 47 } 48 49 static __always_inline bool eth_is_supported_ethertype(__be16 proto) 50 { 51 /* non-Ethernet II unsupported */ 52 return proto >= bpf_htons(ETH_P_802_3_MIN); 53 } 54 55 static __always_inline int eth_load_saddr(struct __ctx_buff *ctx, __u8 *mac, 56 int off) 57 { 58 return ctx_load_bytes(ctx, off + ETH_ALEN, mac, ETH_ALEN); 59 } 60 61 static __always_inline int eth_store_saddr_aligned(struct __ctx_buff *ctx, 62 const __u8 *mac, int off) 63 { 64 return ctx_store_bytes(ctx, off + ETH_ALEN, mac, ETH_ALEN, 0); 65 } 66 67 static __always_inline int eth_store_saddr(struct __ctx_buff *ctx, 68 const __u8 *mac, int off) 69 { 70 #if !CTX_DIRECT_WRITE_OK 71 return eth_store_saddr_aligned(ctx, mac, off); 72 #else 73 void *data_end = ctx_data_end(ctx); 74 void *data = ctx_data(ctx); 75 76 if (ctx_no_room(data + off + ETH_ALEN * 2, data_end)) 77 return -EFAULT; 78 /* Need to use builtin here since mac came potentially from 79 * struct bpf_fib_lookup where it's not aligned on stack. :( 80 */ 81 __bpf_memcpy_builtin(data + off + ETH_ALEN, mac, ETH_ALEN); 82 return 0; 83 #endif 84 } 85 86 static __always_inline int eth_load_daddr(struct __ctx_buff *ctx, __u8 *mac, 87 int off) 88 { 89 return ctx_load_bytes(ctx, off, mac, ETH_ALEN); 90 } 91 92 static __always_inline int eth_store_daddr_aligned(struct __ctx_buff *ctx, 93 const __u8 *mac, int off) 94 { 95 return ctx_store_bytes(ctx, off, mac, ETH_ALEN, 0); 96 } 97 98 static __always_inline int eth_store_daddr(struct __ctx_buff *ctx, 99 const __u8 *mac, int off) 100 { 101 #if !CTX_DIRECT_WRITE_OK 102 return eth_store_daddr_aligned(ctx, mac, off); 103 #else 104 void *data_end = ctx_data_end(ctx); 105 void *data = ctx_data(ctx); 106 107 if (ctx_no_room(data + off + ETH_ALEN, data_end)) 108 return -EFAULT; 109 /* Need to use builtin here since mac came potentially from 110 * struct bpf_fib_lookup where it's not aligned on stack. :( 111 */ 112 __bpf_memcpy_builtin(data + off, mac, ETH_ALEN); 113 return 0; 114 #endif 115 } 116 117 static __always_inline int eth_store_proto(struct __ctx_buff *ctx, 118 const __u16 proto, int off) 119 { 120 return ctx_store_bytes(ctx, off + ETH_ALEN + ETH_ALEN, 121 &proto, sizeof(proto), 0); 122 }