forked from mirrors/linux
		
	bpf: sample BPF_SOCKET_OPS_BASE_RTT program
Sample socket_ops BPF program to test the BPF helper function bpf_getsocketops and the new socket_ops op BPF_SOCKET_OPS_BASE_RTT. The program provides a base RTT of 80us when the calling flow is within a DC (as determined by the IPV6 prefix) and the congestion algorithm is "nv". Signed-off-by: Lawrence Brakmo <brakmo@fb.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked_by: Alexei Starovoitov <ast@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									85cce21578
								
							
						
					
					
						commit
						c890063e44
					
				
					 2 changed files with 79 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -129,6 +129,7 @@ always += tcp_bufs_kern.o
 | 
			
		|||
always += tcp_cong_kern.o
 | 
			
		||||
always += tcp_iw_kern.o
 | 
			
		||||
always += tcp_clamp_kern.o
 | 
			
		||||
always += tcp_basertt_kern.o
 | 
			
		||||
always += xdp_redirect_kern.o
 | 
			
		||||
always += xdp_redirect_map_kern.o
 | 
			
		||||
always += xdp_redirect_cpu_kern.o
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										78
									
								
								samples/bpf/tcp_basertt_kern.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								samples/bpf/tcp_basertt_kern.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
/* Copyright (c) 2017 Facebook
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of version 2 of the GNU General Public
 | 
			
		||||
 * License as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * BPF program to set base_rtt to 80us when host is running TCP-NV and
 | 
			
		||||
 * both hosts are in the same datacenter (as determined by IPv6 prefix).
 | 
			
		||||
 *
 | 
			
		||||
 * Use load_sock_ops to load this BPF program.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <uapi/linux/bpf.h>
 | 
			
		||||
#include <uapi/linux/tcp.h>
 | 
			
		||||
#include <uapi/linux/if_ether.h>
 | 
			
		||||
#include <uapi/linux/if_packet.h>
 | 
			
		||||
#include <uapi/linux/ip.h>
 | 
			
		||||
#include <linux/socket.h>
 | 
			
		||||
#include "bpf_helpers.h"
 | 
			
		||||
#include "bpf_endian.h"
 | 
			
		||||
 | 
			
		||||
#define DEBUG 1
 | 
			
		||||
 | 
			
		||||
#define bpf_printk(fmt, ...)					\
 | 
			
		||||
({								\
 | 
			
		||||
	       char ____fmt[] = fmt;				\
 | 
			
		||||
	       bpf_trace_printk(____fmt, sizeof(____fmt),	\
 | 
			
		||||
				##__VA_ARGS__);			\
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
SEC("sockops")
 | 
			
		||||
int bpf_basertt(struct bpf_sock_ops *skops)
 | 
			
		||||
{
 | 
			
		||||
	char cong[20];
 | 
			
		||||
	char nv[] = "nv";
 | 
			
		||||
	int rv = 0, n;
 | 
			
		||||
	int op;
 | 
			
		||||
 | 
			
		||||
	op = (int) skops->op;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	bpf_printk("BPF command: %d\n", op);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Check if both hosts are in the same datacenter. For this
 | 
			
		||||
	 * example they are if the 1st 5.5 bytes in the IPv6 address
 | 
			
		||||
	 * are the same.
 | 
			
		||||
	 */
 | 
			
		||||
	if (skops->family == AF_INET6 &&
 | 
			
		||||
	    skops->local_ip6[0] == skops->remote_ip6[0] &&
 | 
			
		||||
	    (bpf_ntohl(skops->local_ip6[1]) & 0xfff00000) ==
 | 
			
		||||
	    (bpf_ntohl(skops->remote_ip6[1]) & 0xfff00000)) {
 | 
			
		||||
		switch (op) {
 | 
			
		||||
		case BPF_SOCK_OPS_BASE_RTT:
 | 
			
		||||
			n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION,
 | 
			
		||||
					   cong, sizeof(cong));
 | 
			
		||||
			if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) {
 | 
			
		||||
				/* Set base_rtt to 80us */
 | 
			
		||||
				rv = 80;
 | 
			
		||||
			} else if (n) {
 | 
			
		||||
				rv = n;
 | 
			
		||||
			} else {
 | 
			
		||||
				rv = -1;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			rv = -1;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		rv = -1;
 | 
			
		||||
	}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	bpf_printk("Returning %d\n", rv);
 | 
			
		||||
#endif
 | 
			
		||||
	skops->reply = rv;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
char _license[] SEC("license") = "GPL";
 | 
			
		||||
		Loading…
	
		Reference in a new issue