Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.11 382 lines 8.3 kB view raw
1/* Copyright (c) 2016 VMware 2 * Copyright (c) 2016 Facebook 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of version 2 of the GNU General Public 6 * License as published by the Free Software Foundation. 7 */ 8#define KBUILD_MODNAME "foo" 9#include <uapi/linux/bpf.h> 10#include <uapi/linux/if_ether.h> 11#include <uapi/linux/if_packet.h> 12#include <uapi/linux/ip.h> 13#include <uapi/linux/ipv6.h> 14#include <uapi/linux/in.h> 15#include <uapi/linux/tcp.h> 16#include <uapi/linux/filter.h> 17#include <uapi/linux/pkt_cls.h> 18#include <net/ipv6.h> 19#include "bpf_helpers.h" 20 21#define _htonl __builtin_bswap32 22#define ERROR(ret) do {\ 23 char fmt[] = "ERROR line:%d ret:%d\n";\ 24 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \ 25 } while(0) 26 27struct geneve_opt { 28 __be16 opt_class; 29 u8 type; 30 u8 length:5; 31 u8 r3:1; 32 u8 r2:1; 33 u8 r1:1; 34 u8 opt_data[8]; /* hard-coded to 8 byte */ 35}; 36 37struct vxlan_metadata { 38 u32 gbp; 39}; 40 41SEC("gre_set_tunnel") 42int _gre_set_tunnel(struct __sk_buff *skb) 43{ 44 int ret; 45 struct bpf_tunnel_key key; 46 47 __builtin_memset(&key, 0x0, sizeof(key)); 48 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ 49 key.tunnel_id = 2; 50 key.tunnel_tos = 0; 51 key.tunnel_ttl = 64; 52 53 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 54 if (ret < 0) { 55 ERROR(ret); 56 return TC_ACT_SHOT; 57 } 58 59 return TC_ACT_OK; 60} 61 62SEC("gre_get_tunnel") 63int _gre_get_tunnel(struct __sk_buff *skb) 64{ 65 int ret; 66 struct bpf_tunnel_key key; 67 char fmt[] = "key %d remote ip 0x%x\n"; 68 69 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); 70 if (ret < 0) { 71 ERROR(ret); 72 return TC_ACT_SHOT; 73 } 74 75 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4); 76 return TC_ACT_OK; 77} 78 79SEC("vxlan_set_tunnel") 80int _vxlan_set_tunnel(struct __sk_buff *skb) 81{ 82 int ret; 83 struct bpf_tunnel_key key; 84 struct vxlan_metadata md; 85 86 __builtin_memset(&key, 0x0, sizeof(key)); 87 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ 88 key.tunnel_id = 2; 89 key.tunnel_tos = 0; 90 key.tunnel_ttl = 64; 91 92 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 93 if (ret < 0) { 94 ERROR(ret); 95 return TC_ACT_SHOT; 96 } 97 98 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */ 99 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md)); 100 if (ret < 0) { 101 ERROR(ret); 102 return TC_ACT_SHOT; 103 } 104 105 return TC_ACT_OK; 106} 107 108SEC("vxlan_get_tunnel") 109int _vxlan_get_tunnel(struct __sk_buff *skb) 110{ 111 int ret; 112 struct bpf_tunnel_key key; 113 struct vxlan_metadata md; 114 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n"; 115 116 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); 117 if (ret < 0) { 118 ERROR(ret); 119 return TC_ACT_SHOT; 120 } 121 122 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md)); 123 if (ret < 0) { 124 ERROR(ret); 125 return TC_ACT_SHOT; 126 } 127 128 bpf_trace_printk(fmt, sizeof(fmt), 129 key.tunnel_id, key.remote_ipv4, md.gbp); 130 131 return TC_ACT_OK; 132} 133 134SEC("geneve_set_tunnel") 135int _geneve_set_tunnel(struct __sk_buff *skb) 136{ 137 int ret, ret2; 138 struct bpf_tunnel_key key; 139 struct geneve_opt gopt; 140 141 __builtin_memset(&key, 0x0, sizeof(key)); 142 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ 143 key.tunnel_id = 2; 144 key.tunnel_tos = 0; 145 key.tunnel_ttl = 64; 146 147 __builtin_memset(&gopt, 0x0, sizeof(gopt)); 148 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */ 149 gopt.type = 0x08; 150 gopt.r1 = 1; 151 gopt.r2 = 0; 152 gopt.r3 = 1; 153 gopt.length = 2; /* 4-byte multiple */ 154 *(int *) &gopt.opt_data = 0xdeadbeef; 155 156 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 157 if (ret < 0) { 158 ERROR(ret); 159 return TC_ACT_SHOT; 160 } 161 162 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt)); 163 if (ret < 0) { 164 ERROR(ret); 165 return TC_ACT_SHOT; 166 } 167 168 return TC_ACT_OK; 169} 170 171SEC("geneve_get_tunnel") 172int _geneve_get_tunnel(struct __sk_buff *skb) 173{ 174 int ret; 175 struct bpf_tunnel_key key; 176 struct geneve_opt gopt; 177 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n"; 178 179 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); 180 if (ret < 0) { 181 ERROR(ret); 182 return TC_ACT_SHOT; 183 } 184 185 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt)); 186 if (ret < 0) { 187 ERROR(ret); 188 return TC_ACT_SHOT; 189 } 190 191 bpf_trace_printk(fmt, sizeof(fmt), 192 key.tunnel_id, key.remote_ipv4, gopt.opt_class); 193 return TC_ACT_OK; 194} 195 196SEC("ipip_set_tunnel") 197int _ipip_set_tunnel(struct __sk_buff *skb) 198{ 199 struct bpf_tunnel_key key = {}; 200 void *data = (void *)(long)skb->data; 201 struct iphdr *iph = data; 202 struct tcphdr *tcp = data + sizeof(*iph); 203 void *data_end = (void *)(long)skb->data_end; 204 int ret; 205 206 /* single length check */ 207 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) { 208 ERROR(1); 209 return TC_ACT_SHOT; 210 } 211 212 key.tunnel_ttl = 64; 213 if (iph->protocol == IPPROTO_ICMP) { 214 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ 215 } else { 216 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) 217 return TC_ACT_SHOT; 218 219 if (tcp->dest == htons(5200)) 220 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ 221 else if (tcp->dest == htons(5201)) 222 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */ 223 else 224 return TC_ACT_SHOT; 225 } 226 227 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0); 228 if (ret < 0) { 229 ERROR(ret); 230 return TC_ACT_SHOT; 231 } 232 233 return TC_ACT_OK; 234} 235 236SEC("ipip_get_tunnel") 237int _ipip_get_tunnel(struct __sk_buff *skb) 238{ 239 int ret; 240 struct bpf_tunnel_key key; 241 char fmt[] = "remote ip 0x%x\n"; 242 243 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); 244 if (ret < 0) { 245 ERROR(ret); 246 return TC_ACT_SHOT; 247 } 248 249 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4); 250 return TC_ACT_OK; 251} 252 253SEC("ipip6_set_tunnel") 254int _ipip6_set_tunnel(struct __sk_buff *skb) 255{ 256 struct bpf_tunnel_key key = {}; 257 void *data = (void *)(long)skb->data; 258 struct iphdr *iph = data; 259 struct tcphdr *tcp = data + sizeof(*iph); 260 void *data_end = (void *)(long)skb->data_end; 261 int ret; 262 263 /* single length check */ 264 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) { 265 ERROR(1); 266 return TC_ACT_SHOT; 267 } 268 269 key.remote_ipv6[0] = _htonl(0x2401db00); 270 key.tunnel_ttl = 64; 271 272 if (iph->protocol == IPPROTO_ICMP) { 273 key.remote_ipv6[3] = _htonl(1); 274 } else { 275 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) { 276 ERROR(iph->protocol); 277 return TC_ACT_SHOT; 278 } 279 280 if (tcp->dest == htons(5200)) { 281 key.remote_ipv6[3] = _htonl(1); 282 } else if (tcp->dest == htons(5201)) { 283 key.remote_ipv6[3] = _htonl(2); 284 } else { 285 ERROR(tcp->dest); 286 return TC_ACT_SHOT; 287 } 288 } 289 290 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 291 if (ret < 0) { 292 ERROR(ret); 293 return TC_ACT_SHOT; 294 } 295 296 return TC_ACT_OK; 297} 298 299SEC("ipip6_get_tunnel") 300int _ipip6_get_tunnel(struct __sk_buff *skb) 301{ 302 int ret; 303 struct bpf_tunnel_key key; 304 char fmt[] = "remote ip6 %x::%x\n"; 305 306 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 307 if (ret < 0) { 308 ERROR(ret); 309 return TC_ACT_SHOT; 310 } 311 312 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]), 313 _htonl(key.remote_ipv6[3])); 314 return TC_ACT_OK; 315} 316 317SEC("ip6ip6_set_tunnel") 318int _ip6ip6_set_tunnel(struct __sk_buff *skb) 319{ 320 struct bpf_tunnel_key key = {}; 321 void *data = (void *)(long)skb->data; 322 struct ipv6hdr *iph = data; 323 struct tcphdr *tcp = data + sizeof(*iph); 324 void *data_end = (void *)(long)skb->data_end; 325 int ret; 326 327 /* single length check */ 328 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) { 329 ERROR(1); 330 return TC_ACT_SHOT; 331 } 332 333 key.remote_ipv6[0] = _htonl(0x2401db00); 334 key.tunnel_ttl = 64; 335 336 if (iph->nexthdr == NEXTHDR_ICMP) { 337 key.remote_ipv6[3] = _htonl(1); 338 } else { 339 if (iph->nexthdr != NEXTHDR_TCP) { 340 ERROR(iph->nexthdr); 341 return TC_ACT_SHOT; 342 } 343 344 if (tcp->dest == htons(5200)) { 345 key.remote_ipv6[3] = _htonl(1); 346 } else if (tcp->dest == htons(5201)) { 347 key.remote_ipv6[3] = _htonl(2); 348 } else { 349 ERROR(tcp->dest); 350 return TC_ACT_SHOT; 351 } 352 } 353 354 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 355 if (ret < 0) { 356 ERROR(ret); 357 return TC_ACT_SHOT; 358 } 359 360 return TC_ACT_OK; 361} 362 363SEC("ip6ip6_get_tunnel") 364int _ip6ip6_get_tunnel(struct __sk_buff *skb) 365{ 366 int ret; 367 struct bpf_tunnel_key key; 368 char fmt[] = "remote ip6 %x::%x\n"; 369 370 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 371 if (ret < 0) { 372 ERROR(ret); 373 return TC_ACT_SHOT; 374 } 375 376 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]), 377 _htonl(key.remote_ipv6[3])); 378 return TC_ACT_OK; 379} 380 381 382char _license[] SEC("license") = "GPL";