-
Notifications
You must be signed in to change notification settings - Fork 0
/
xdp-tutorial.db
1 lines (1 loc) · 45.9 KB
/
xdp-tutorial.db
1
{"gitRepoUrl": "https://github.com/xdp-project/xdp-tutorial.git", "commitId": "1a0b4c8e7ba5f7eebb9f2af85843ae71324cfdec", "humanFuncDescription": [{"filePath": "basic04-pinning-maps/xdp_loader.c", "funcName": "pin_maps_in_bpf_object", "startLine": 73, "endLine": 107, "description": "pin_maps_in_bpf_object() function is used to check if a file exists and unpin all maps in that directory. Function takes as arguments structure pointer 'bpf_obj' of type bpf_object and 'cfg' of type config. It then initializes a character array 'map_filename' of size PATH_MAX, which is a predefined macro of size 4096, and two integer variables 'err' and 'len'. It then uses snprintf() function to put 'pin_basedir', 'cfg->ifname' and 'map_name' in len variable. If len<0, we print an error message 'ERR: creating map_name'. If access to that map_filename is not equal to -1, we check if verbose, which is defined in file 'common_params.o' as 1 is true. If true, we print the message that we are unpinning previous maps in which configuration. bpf_object__unpin_maps() function is then used to unpin each map contained within the BPF object found in the cfg->pin_dir. If unsuccessful, i.e. err!=0, it displays an error message stating error in unpinning maps in that directory and returns 'EXIT_FAIL_BPF'. We then go on to check if verbose is TRUE, and the print a comment stating 'Pinning maps' in that directory. Finally we use bpf_object__pin_maps() function to pin each map contained within the BPF object 'bpf_obj' at the directory cfg->pin_dir. If error, returns EXIT_FAIL_BPF. Function returns 0 on successful completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "18.03.2023"}, {"filePath": "basic04-pinning-maps/xdp_loader.c", "funcName": "main", "startLine": 109, "endLine": 165, "description": "xdp_loader_main() function is used to load XDP program to configuration. It takes as argument integer 'argc' and pointer to pointer array 'argv' of type character. It initializes two integer variables 'err' and 'len', a pointer bpf_obj of type struct bpf_object and structure 'cfg' of type config. strncpy() is used to set default BPF-ELF object file and BPF program name. parse_cmdline_args() function parses the command line arguments and stores them in a config cfg. If cfg.ifindex is equal to -1, it prints a error message 'ERR: required option --dev missing' and returns EXIT_FAIL_OPTION. If cfg.do_unload is TRUE then if reuse of maps is set as TRUE then we skip pinning of maps. We then pin the base directory to the configuration ifname and if error happens, print an error message 'ERR: creating pin dirname' and return EXIT_FAIL_OPTION. load_bpf_and_xdp_attach() function is then called with 'cfg' value and value is stored in bpf_obj. If bpf_obj is NULL, it returns EXIT_FAIL_BFP. If 'verbose' is TRUE, we print two messages: 'successful in loading BPF-object 'filename' and used section 'cfg.progsec'' and 'XDP prog attached on device 'cfg.ifname'(ifindex: 'cfg.ifindex')'. If reuse maps is NULL, we display message stating error in pinning maps. Function returns EXIT_OK on successful completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "18.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "find_map_fd", "startLine": 63, "endLine": 78, "description": "find_map_fd() is a function used to find the file descriptor of a map. This function takes as input pointer 'bpf_obj' of type structure bpf_object and pointer 'mapname' of type constant character. It defines pointer 'map' of type structure bpf_map and an integer variable map_fd with value -1. bpf_object__find_map_by_name() function is then used to return BPF map of the given name, if it exists within the passed BPF object 'bpf_obj' and the return value is stored in 'map'. If map is NULL, we print error message stating we can't find map by name and go to 'out'. 'out' is defined later in the function as 'return map_fd'. map_fd function is used to get the file descriptor of the map. Function returns map_fd on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "19.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "gettime", "startLine": 81, "endLine": 92, "description": "gettime() function is used to get the time in nanoseconds. It is a static function of type __u64. It defines a structure 't' of type timespec and an integer variable 'res'. clock_gettime() function is called on CLOCK_MONOTONIC and t to retreive the time of the specified clock CLOCK_MONOTONIC and store it in res. If res is negative, we print error message 'Error with gettimeofday! 'res''. Function returns the time after calculating it in nanoseconds.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "19.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "calc_period", "startLine": 103, "endLine": 113, "description": "calc_period() is used to calculate the time difference between two records. It is a static function of type double which takes as input two structure pointers 'r' and ' p' both of type record. It initializes variable 'period_' of type double and 'period' of type __u64 as 0 each. Function then calculates period as difference of timestamp of r and p. If period is positive we calculate 'period_' by typecasting 'period' as 'double' after dividing it by macro 'NANOSEC_PER_SEC'. Function returns period_ on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "19.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "stats_print", "startLine": 115, "endLine": 141, "description": "stats_print() function is used to get details of two records 'rec' and 'prev'. It is a static function of type void which takes as input two structure pointers 'stats_rec' and 'stats_prev' of type stats_record. It declares two structure pointer 'rec' and 'prev' of type record; two variables 'period' and 'pps' of type double; and a variable 'packets' of type __u64. It then calculates the packets per seconds and prints it. action2str() function is then used to return a string representation of the XDP action, which is used to print out a description for each statistic record printed by stats_print(). Function stores two records in 'rec' and'prev' and then uses calc_period() to calculate the time difference between these two records and store it in variable\n'period'. if period is equal to 0 then we simply return. The difference in total rx packets of 'rec' and 'prev' is stored in 'period'. Variable 'pps' is calculated by dividing 'packets' by 'period'. We print fmt, action, total packets of rec, pps and period. Function returns no value on.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "19.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "map_get_value_array", "startLine": 144, "endLine": 150, "description": "map_get_value_array() is used to get an array of values from BPF map. Function takes as input function of type void which takes as input an integer 'fd', a variable 'key' of type __u32 and a structure pointer 'value' of type datarec. 'fd' is used to represent a file descriptor. It uses bpf_map_lookup_elem() helper function to look for file descriptor fd associated with 'key' and return it 'value'. If this 'value' is not equal to NULL, we print error stating 'bpf_map_lookup_elem; failed key.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "19.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "map_get_value_percpu_array", "startLine": 153, "endLine": 160, "description": "map_get_value_percpu_array() is a void function which prints an error message to 'stderr' stating that this function is not yet implemented. Function takes as argument an integer variable 'fd', a 'key' of type __u32 and a structure pointer 'value' of type datarec.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "22.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "map_collect", "startLine": 162, "endLine": 185, "description": "map_collect() function calls the appropriate map getter based on the type of BPF Map. It is a static boolean function which takes as input an integer variable 'fd', two variables 'map_type' and 'key' of type __u32 and a structure pointer 'rec' of type record. It defines a structure 'value' of type datarec. It then uses gettime() function to update timestamp of record 'rec'. It then initializes a switch case with the case checker being 'map_type'. If map_type is 'BPF_MAP_TYPE_ARRAY', we call map_get_value_array() function with 'fd', 'key' and '&value' and break. If map_type is 'BPF_MAP_TYPE_PERCPU_ARRAY', we fall through. The default condition is to print an error stating 'Unknown map_type. Cannot handle' and return false and break. Total rx_packets are updated in 'rec'. Function returns true on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "22.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "stats_collect", "startLine": 187, "endLine": 194, "description": "stats_collect() function is used to collect the statistics from the map. It is a static void function which takes as argument an integer variable 'map_fd', a variable 'map_type' of type __u32 and a structure pointer 'stats_rec' of type stats_record. Function stores XDP_PASS in a variable 'key' of type __u32. It then calls the map_collect() function with XDP_PASS as key which will return all of the statistics for packets passed through by XDP. The stats_record structure contains an array of counters for all actions that can be taken by XDP.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "22.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "stats_poll", "startLine": 196, "endLine": 219, "description": "stats_poll() function collects the statistics of the XDP program running on a particular interface. It is a static void function which takes as input two integer variables 'map_fd' and 'interval' and a variable 'map_type' of type __u32. It initializes two structure variable 'prev' and 'record' as 0 of type stats_record. It sets 'LC_NUMERIC' as English and then prints the header for stats as 'XDP-ACTION'. It then calls stats_collect() function with map_fd, map_type and record as arguments to get initial reading quickly. It then runs an infinite while loop to collect and print statistics of records.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "22.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "__check_map_fd_info", "startLine": 225, "endLine": 268, "description": "__check_map_fd_info() function is used to check the map information. It is a static int function which takes as input an integer variable\n'map_fd' and two structure pointers 'info' and 'exp' of type bpf_map_info. Function initializes a variable 'info_len' of type __u32 as size of 'info' and an integer variable 'err'. If 'map_fd' is negative we return EXIT_FAIL. It uses bpf_obj_get_info_by_fd() function to get information on 'map_fd'. If error, we print message 'ERR: can't get info' and return EXIT_FAIL_BPF. We further check for map 'key size', 'value size', 'max_entries' and 'type' mismatch and print message with expected values of same in case of mismatch. We return EXIT_FAIL in all four cases. Function returns 0.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "22.03.2023"}, {"filePath": "basic03-map-counter/xdp_load_and_stats.c", "funcName": "main", "startLine": 270, "endLine": 337, "description": "xdp_load_and_stats_main() function is used to call all the other functions. It takes as input an integer variable 'argc' and a pointer to pointer 'argv' of type character. It defines two structures: 'map_expect' and 'info' of type bpf_map_info as 0. It also defines structure pointer 'bpf_obj' of type bpf_object, and three integer variables 'stats_map_fd', 'err' and 'interval'(equal to 2). strncpy() function is used to set default BPF-ELF object file and BPF program name. cfg.ifindex id used to check if the required option is missing or not. If 'cfg.do_unload' is true, we use xdp_link_detach() to detach the XDP program from the interface. We then call load_bpf_and_xdp_attach() function with 'cfg' as argument and store it in bpf_obj. If bpf_obj is FALSE, we return EXIT_FAIL_BPF. If 'verbose' is TRUE, we print message stating successful in loading BPF-object of filename and used this section of program section; followed by another message 'XDP program attached on device ifname with it's ifindex'. We then use find_map_fd() to locate map descriptor file. Finally, we check if map info is of expected size and prints an error message if not. If 'verbose' is TRUE, we collect stats like type, id, name, key_size, value_size and max_entries of BPF map and print it. stats_poll() function is called to collect the statistics of the XDP program running on that interface. Function returns 'EXIT_OK' on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "22.03.2023"}, {"filePath": "tracing04-xdp-tcpdump/xdp_sample_pkts_kern.c", "funcName": "xdp_sample_prog", "startLine": 35, "endLine": 69, "description": "The function xdp_sample_prog sends data and packet sample into user space via perf event.\n The function xdp_sample_prog takes ctx of type struct xdp_md as input. struct xdp_md is the metadata for the XDP packet.\n Two pointers data and data_end points to the start and end of the XDP packet data respectively.\n The packet contents are in between ctx->data and ctx->data_end.\n If data is less than data_end, it performs the following:\n A variable named flags of type __u64 is set to BPF_F_CURRENT_CPU, which indicates that the value for the current CPU should be retrieved.\n A structure variable named metadata of type struct S is declared. struct S consists of the fields cookie and pkt_len, both of type __u16.\n metadata.cookie is set to value 0xdead and metadata.pkt_len is set to data_end - data.\n A variable named sample_size of type __u16 is set to min(metadata.pkt_len, SAMPLE_SIZE), where SAMPLE_SIZE = 1024ul.\n The sample_size is left shifted 32 bits and a bitwise OR operation is performed with flag. After the calculations, the flag variable is updated with that value.\n Using helper function bpf_perf_event_output(ctx, &my_map, flags, &metadata, sizeof(metadata)), sizeof(metadata) bytes of data from metadata gets copied to BPF perfbuf my_map, which is of type BPF_MAP_TYPE_PERF_EVENT_ARRAY.\n The helper function also needs ctx, which is a pointer to the context on which the tracing program is executed.\n On successfully copying the data, the helper function returns 0 which is stored in an integer variable ret.\n If ret == 0, it will call bpf_printk() which is a wrapper to bpf_trace_printk() to print the error message 'perf_event_output failed' along with the ret value to the common tracepipe.\n If data is not less than data_end, the function returns XDP_PASS, which indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "21.02.2023"}, {"filePath": "experiment01-tailgrow/xdp_prog_fail1.c", "funcName": "_xdp_fail1", "startLine": 14, "endLine": 46, "description": " The function tries to use the packet length (calculated as data_end - data) to access the last byte as an offset added to data. \n The verifier rejects this, as the dynamic length calculation cannot be used for static analysis.\n The function _xdp_fail1 takes ctx of type struct xdp_md as input. \n The packet contents are between ctx->data and ctx->data_end.\n The length of the packet is stored in unsigned interger variable named offset.\n pos is a void pointer pointing to the start of data packet.\n If the packet lies in between the data and data_end it return XDP_PASS.\n XDP_PASS indicates that the packet should be forwarded to the normal network stack for further processing. \n The XDP program can modify the content of the package before this happens.\n Else, it will return XDP_ABORTED which indicates the packet will be dropped.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "14.02.2023"}, {"filePath": "experiment01-tailgrow/xdp_prog_kern2.c", "funcName": "_xdp_end_loop", "startLine": 19, "endLine": 63, "description": "The function _xdp_end_loop verifies that the data buffer processed is valid, and it returns XDP_ABORTED if it is not. The function _xdp_end_loop takes ctx of type struct xdp_md as input. Two pointers data and data_end points to the start and end of the packet data respectively. The packet contents are in between ctx - > data and ctx - > data_end. Variable offset is initialized with a minimum length which is stored in a constant MIN_LEN = 14. The void pointer pos initially points to the start of the received packet. A for loop will execute for each bit in the ethernet packet[MTU - MIN_LEN i.e.1536 - 14 which represents the ethernet packet(Ethernet Header + MTU)], and checks if pos plus offset is greater than data_end then it returns XDP_PASS. XDP_PASS indicates that the packet should be forwarded to the normal network stack for further processing. If pos plus offset is equal to data_end then calculate ptr = pos + (offset - sizeof( * ptr)). If * ptr == 0xFF, it returns XDP_ABORTED.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "20.02.2023"}, {"filePath": "tracing03-xdp-debug-print/trace_read.c", "funcName": "print_ether_addr", "startLine": 16, "endLine": 24, "description": "Function print_ether_addr() prints the ehternet protocol type\n \t\t and the ethernet address. It is of type static and takes as\n input a constant character pointer 'type' and a character\n pointer 'str'. It defines a variable 'addr' of type __u64,\n i.e. unsigned 64 bit integer. First argument of scanf is\n passed to 'addr' and if it equals 1, then ether_ntoa() \n function is called with a pointer to 'addr' typecast as a \n structure pointer of type 'ether_addr'. ether_ntoa() function\n converts the 48-bit Ethernet host address addr from the \n standard hex-digits-and-colons notation into binary data in\n network byte order and returns a pointer to it in a statically\n allocated buffer, which subsequent calls will overwrite. Function\n ether_aton() returns NULL if the address is invalid. This \n basically prints out the MAC address in human-readable format ", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "10.03.2023"}, {"filePath": "tracing03-xdp-debug-print/trace_read.c", "funcName": "main", "startLine": 26, "endLine": 71, "description": "trace_read_main() function is used to print MAC addresses of source and\n \t\t destination and protocol. It takes as argument integer 'argc' and pointer \n to pointer array 'argv' of type character. It initializes variables\n FILE pointer 'stream', 'line' of type character pointer, 'len' of\n type size_t as 0 and 'nread' of type ssize_t. Function opens\n TRACEFS_PIPE for reading while displaying error message in case of \n unsuccessful opening. It reads each line using the function 'strtok_r()'\n and splits on the basis of delimeter ' '. Function then prints the\n source MAC address, destination MAC address and protocol details for\n each line. Finally it closes the stream when all lines have been read.\n Function returns 'EXIT_OK' on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "17.03.2023"}, {"filePath": "advanced03-AF_XDP/af_xdp_kern.c", "funcName": "xdp_sock_prog", "startLine": 22, "endLine": 41, "description": "xdp_sock_prog() function takes as input structure ctx of type\n xdp_md. It finds rx_queue_index from ctx and stores it in 'index'.\n This index is used as key to xdp_stats_map in helper function\n 'bpf_map_lookup_elem'. If we receive a match, we increment packet\n count. If packet-count and 1 evaluate to TRUE,we return XDP_PASS. \n We then again use bpf_map_lookup_elem() to lookup whether an entry\n exists for 'xsks_map' with 'index' as key. If yes, we redirect packets\n in that queue to a socket using helper function bpf_redirect_map().\n Function returns XDP_PASS on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "27.02.2023"}, {"filePath": "packet-solutions/xdp_vlan01_kern.c", "funcName": "proto_is_vlan", "startLine": 21, "endLine": 25, "description": "This function checks is the packet has vlan tunnel header.\n proto_is_vlan(eth->h_proto) takes the ethernet frame's packet type ID field as input.\n The bpf_htons function takes a 16-bit number in host byte order and returns a 16-bit number in network byte order used in TCP/IP networks.\n If input argument h_proto is equal to the network byte order of ETH_P_8021Q (802.1Q VLAN Extended Header) or ETH_P_8021AD (802.1ad Service VLAN), it will return true,\n else it will return false.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "17.02.2023"}, {"filePath": "packet-solutions/xdp_vlan01_kern.c", "funcName": "parse_ethhdr", "startLine": 42, "endLine": 79, "description": "The function will parse packet header, by traversing VLAN headers till VLAN_MAX_DEPTH, do bounds checking for header information, and return the next header type and position.\n parse_ethhdr() takes the following input parameters: nh which is a pointer to an element of struct hdr_cursor, a void pointer data_end, and ethhdr, a pointer to pointer of type struct ethhdr).\n Varibale nh is of type struct hdr_cursor. struct hdr_cursor stores a void pointer pos, which is used to keep track of the current parsing position.\n eth points to the current parsing postion of the header. int hdrsize stores the Ethernet frame size.\n struct vlan_hdr is a data structure to vlan header, which consist of 2 feilds: h_vlan_TCI of type __be16 to store the priority and VLAN ID and h_vlan_encapsulated_proto of type __be16 to store packet type ID or len.\n It checks if current pointer plus size of header is greater than data_end, it returns -1.\n The current pointer is updated to current pointer plus the header size.\n ethhdr points to the eth and vlh points to the current parsing postion of the header. \n h_proto is initialized with the eth->h_proto value.\n #pragma unroll is used to avoid the verifier restriction on loops.\n It runs a for loop for VLAN_MAX_DEPTH=10 times, each time first checks if proto_is_vlan(h_proto) is 0 or not. If it is 0 then it break and come out of the loop.\n It also checks if the vlh plus 1 exceeds data_end, if true it break. \n h_proto is updated to vlh->h_vlan_encapsulated_proto and vlh is increamented by 1.\n Once the for is executed, the curerent parsing position is updated with the position pointed by vlh.\n And finally the h_proto which is the IP port no in network-byte-order is returned.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "17.02.2023"}, {"filePath": "packet-solutions/xdp_vlan01_kern.c", "funcName": "xdp_vlan_01", "startLine": 82, "endLine": 115, "description": "This function checks if the innermost packet header (up to VLAN_MAX_DEPTH) is a VLAN header, if so it drops the packet. It also drops if the packet if the innermost header is invalid.\n The function xdp_vlan_01 takes ctx of type struct xdp_md as input. \n Two pointers data_end and data point to the end and the start of the packet data. \n The packet contents are between ctx->data and ctx->data_end.\n Varibale nh is of type struct hdr_cursor. struct hdr_cursor stores a void pointer pos, which is used to keep track of the current parsing position.\n nh.pos initially points to the start of the packet data.\n eth is a pointer to an element of a structure ethhdr, ethhdr is an Ethernet frame header defined in <linux/if_ether.h>\n parse_ethhdr(&nh, data_end, ð) takes the current parsing position nh, the pos of packet end, and the eth as input and returns the packet type ID (or EtherType) which is stored in an integer variable nh_type.\n If nh_type < 0 i.e an invalid EtherType, it returns XDP_ABORTED.\n Else it checks if proto_is_vlan(eth->h_proto) is true, it returns XDP_DROP.\n proto_is_vlan(eth->h_proto) takes the ethernet frame's packet type ID field as input and checks if eth->h_proto is equal to the 16-bit number in network byte order of ETH_P_8021Q (802.1Q VLAN Extended Header) or ETH_P_8021AD (802.1ad Service VLAN).\n That means if the eth->h_proto is of type 802.1Q VLAN Extended Header or 802.1ad Service VLAN, it returns XDP_DROP, which means all the incoming packets will be dropped.\n Else it returns XDP_PASS, indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "17.02.2023"}, {"filePath": "experiment01-tailgrow/xdp_prog_fail2.c", "funcName": "_xdp_fail2", "startLine": 14, "endLine": 34, "description": "The function tries to find the last byte in the packet.\n The function _xdp_fail2 takes ctx of type struct xdp_md as input. \n The void pointer data_end points to the end of a packet data.\n The void pointer pos of type volatile also points to the end of the packet data.\n #pragma clang optimize off used to to selectively enable optimization.\n #pragma clang optimize on does not selectively enable additional optimizations when compiling at low optimization levels. \n This feature can only be used to selectively disable optimizations.\n if pos-1 > data_end which checks the data access out of bound and return XDP_PASS.\n XDP_PASS indicates that the packet should be forwarded to the normal network stack for further processing. \n A unsigned char pointer ptr of type volatile points to the second last position on in the packet.\n if ptr is equal to 0XFF then it will return XDP_ABORTED, which indicates the packet will be dropped.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "17.02.2023"}, {"filePath": "experiment01-tailgrow/xdp_prog_kern3.c", "funcName": "_xdp_works1", "startLine": 15, "endLine": 56, "description": "The function looks at the last second last byte and if the value is 0xFF drops the packet at XDP hookpoint, otherwise the packet is allowed to pass.\n The function _xdp_works1 takes ctx of type struct xdp_md as input. struct xdp_md is the metadata for XDP packet. \n Two pointers data and data_end points to the start and end of the XDP packet data respectively.\n The packet contents are in between ctx->data and ctx->data_end.\n The length of the packet is calculated by data_end - data and stored in the offset variable.\n barrier_var() operation that makes specified variable \"a black box\" for optimizing the compiler.\n The offset value is decremented by 1 and updated after performing a bitwise AND operation with 0x7FFF.\n A void pointer pos initially point to the start of the XDP packet. Then it is forwarded by adding the offset to it.\n Now it checks if the pos + 1 is greater than data_end, it returns XDP_DROP, which means it will drop all incoming packets.\n Also, an unsigned char pointer ptr points to the location where the pos are pointing. If ptr is pointing to a value 0xFF, it returns XDP_ABORTED, which means it will drop the packet with a tracepoint exception.\n Else the function returns XDP_PASS. XDP_PASS indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "20.02.2023"}, {"filePath": "basic01-xdp-pass/xdp_pass_kern.c", "funcName": "xdp_prog_simple", "startLine": 6, "endLine": 9, "description": "xdp_prog_simple() function takes as input structure ctx\n of type xdp_md. It returns XDP_PASS value.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "27.02.2023"}, {"filePath": "experiment01-tailgrow/xdp_prog_fail3.c", "funcName": "_xdp_fail3", "startLine": 21, "endLine": 55, "description": "The function uses packet length to find and access last byte in packet. NOTE: The verifier cannot see this is safe, as it cannot deduce the packet length at verification time. The function _xdp_fail3 takes ctx of type struct xdp_md as input. Two pointers data and data_end points to the start and end of the packet data respectively. The packet contents are in between ctx - > data and ctx - > data_end. The length of the packet is stored in interger variable named offset of type __u64. The maximum offset value, MAX_PACKET_OFF is set to 0x7fff(32767 in decimal). 'offset & 0xFFFF' is used to mask the low 16 bits of offset and updated to offset. If the offset value is less than 2, the offset is updated to 2. Then it will check whether the start of the packet data plus the offset is greater than the packet_end.On true, it will return XDP_PASS. XDP_PASS indicates that the packet should be forwarded to the normal network stack for further processing. Else if the start of the packet data plus the offset is less than the packet_end, the pointer ptr is initialized with data plus(offset - sizeof( * ptr)) value. If ptr is eqaul to 0XFF, it will return XDP_ABORTED, which indicates the packet will be dropped.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "17.02.2023"}, {"filePath": "common/common_libbpf.c", "funcName": "IS_ERR_OR_NULL", "startLine": 14, "endLine": 17, "description": "IS_ERR_OR_NULL() is used to check if pointer is null or undefined. It is a static inline function of type boolean which takes as input a constant void pointer ptr. If on typecasting 'ptr' to type unsigned long, it returns error then IS_ERR_OR_NULL() returns True, else false. Function returns value of IS_ERR_OR_NULL() or negated value of ptr.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "27.02.2023"}, {"filePath": "common/common_libbpf.c", "funcName": "bpf_prog_load_xattr_maps", "startLine": 24, "endLine": 162, "description": "bpf_prog_load_xattr_maps() is called to load the eBPF program. It takes as input a constant struct pointer 'attr' of type bpf_prog_load_attr_maps, a structure pointer to pointer 'pobj' of type bpf_object and an integer pointer 'prog_fd'. Function then initializes three structures:\nbpf_object_open_attr, bpf_object and bpf_map; two enums: bpf_attach_type and bpf_prog_type; and two integers 'err' and 'i'. It checks if attribute or attribute file is NULL ad returns error '-EINVAL' or invalid value. 'open_attr' which is defined earlier of type struct bpf_object_open_attr, is passed as argument to bpf_object__open_xattr() function and the value is stored in 'obj' of type bpf_object. If obj is error or NULL, returns error '-ENOENT'. It assigns attribute of prog_type to prog_type and expected attach type of attr using function bpf_object__for_each_program. If 'first_prog', which is a struct of type bpf_prog, is not NULL, assign first_prog as prog. Then we reset attr->pinned_maps.map_fd to identify successful file load by running a for loop from i=0 to attr->nr_pinned_maps and update the map_fd for each to -1. We load the map for each file. If first_prog is not NULL, we give a warning stating that 'object file doesn't contain bpf program' and close the object. We then use bpf_map__for_each function to pin the maps that were not loaded via pinned filename. If matched, we check if map is already loaded and continue. Also check if map needs to be pinned. We finally use a for loop to iterate over the pinned maps and print a warning if the requested mapname is not seen. We update 'pobj' pointer to obj and prog_fd pointer to 'first_prog' via bpf_program_fd. Function returns \n 0 on completion.", "author": "Neha Chowdhary", "authorEmail": "[email protected]", "date": "10.03.2023"}, {"filePath": "packet-solutions/xdp_vlan02_kern.c", "funcName": "__parse_ethhdr_vlan", "startLine": 22, "endLine": 65, "description": "The function __parse_ethhdr_vlan parses the Ethernet header and VLAN header and returns the protocol number stored in Ethernet's packet in network byte order, if VLAN header is not present. Otherwise, it returns the protocol number in the VLAN header.\n\t \t\t\t\t The function __parse_ethhdr_vlan takes the following arguments as input to the function: a pointer to a struct hdr_cursor, a pointer data_end to point to the end of the packet data, ethhdr which is a pointer to a pointer to an ethhdr struct and a pointer to a collect_vlans struct.\n\t\t\t\t\t 'hdr_cursor' stores the current position of the packet being parsed. 'ethhdr' which will be set to the currently parsed Ethernet header. 'collect_vlans' struct, stores any VLAN header information found in the packet.\n\t\t\t\t\t It checks if nh->pos + hdrsize > data_end i.e if the current parsing position plus the header size exceeds the location pointing to the end of the packet then it is an invalid packet, hence returns 0.\n\t\t\t\t\t Else the pointer moves to the next header by performing nh->pos += hdrsize.\n\t\t\t\t\t Then, the function checks if the Ethernet header contains any VLAN encapsulation by looping over the header and looking for VLAN header information. The loop is unrolled to avoid verification restrictions on loops, and it supports up to VLAN_MAX_DEPTH layers of VLAN encapsulation. The function retrieves the VLAN header information and stores it in the collect_vlans struct if it is provided.\n\t\t\t\t\t Finally, the function sets the cursor position to the end of the VLAN headers and returns the protocol number from the Ethernet header in network-byte-order.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "24.04.2023"}, {"filePath": "packet-solutions/xdp_vlan02_kern.c", "funcName": "xdp_vlan_02", "startLine": 69, "endLine": 127, "description": "The function xdp_vlan_02 parses incoming Ethernet packets and extracts VLAN tags. It checks if the id of the second VLAN tag is 42, it returns XDP_ABORTED. Else, it returns XDP_PASS. The function xdp_vlan_02 takes ctx of type struct xdp_md as input. Two pointers data_end and data point to the end and the start of the packet data. The packet contents are between ctx->data and ctx->data_end. Varibale nh is of type struct hdr_cursor. struct hdr_cursor stores a void pointer pos, which is used to keep track of the current parsing position. nh.pos initially points to the start of the packet data. Varibale vlans is of type struct collect_vlans. struct collect_vlans is structure to collect VLANs after parsing via parse_ethhdr_vlan. eth is a pointer to an element of a structure ethhdr, ethhdr is an Ethernet frame header defined in <linux/if_ether.h>. The function parse_ethhdr_vlan(&nh, data_end, ð, &vlans) takes the current parsing position nh, the pos of packet end, the eth and vlans as input. It parses the ethernet header and checks if this is a VLAN tagged packet. If true it returns the ethernet type field which stored in variable eth_type of type int. If eth_type < 0 i.e an invalid EtherType, it returns XDP_ABORTED. It checks if vlans.id[1] == 42 i.e. ff the second VLAN tag in the packet is 42, the function returns XDP_ABORTED. Else it returns XDP_PASS, indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "20.02.2023"}, {"filePath": "basic04-pinning-maps/xdp_prog_kern.c", "funcName": "ether_addr_to_u64", "startLine": 20, "endLine": 28, "description": "ether_addr_to_u64() function takes an array named addr which stores values of type const__u8. ETH_ALEN is a constant defined in < if_ether.h > whose value is 6 which represents octets in one ethernet addr. A variable u of type __u64 is initialized to 0. A for loop will execute 6 times i.e.( for values i = 0 to i = ETH_ALEN - 1 i.e.6 - 1 = 5) Each time the variable 'u' is left shifted by 8 bits and then the binary OR operation is performed where operand 1 is u left shifted by 8 and operand 2 is the value at ith index in the array addr i.e.addr[i]. The result of OR is 1 if any of the two bits is 1 which is updated to the variable u. The function returns the value of u after executing the for loop", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "20.02.2023"}, {"filePath": "basic04-pinning-maps/xdp_prog_kern.c", "funcName": "xdp_prog_simple", "startLine": 31, "endLine": 47, "description": "The function xdp_prog_simple takes ethernet address as an array of unsigned bytes of size 8 as input, converts it into a 64 byte unsigned integer and returns the ethernet address as a 64 byte integer. The function process an ethernet packet. The function xdp_prog_simple takes ctx of type struct xdp_md as input. Two pointers data and data_end points to the start and end of the packet data respectively. eth is a pointer to structure ethhdr where struct ethhdr represents an Ethernet frame header defined in Linux < if_ether.h > The size of the ethernet header is stored in a variable offset of type __u64. It checks if eth plus offset is greater than data_end, it returns 0. The helper function bpf_printk() is used to dump the following information about the ethernet packet: eth - > h_source(source hardware address), eth - > h_dest(destination hardware address), and eth - > h_proto(protocol type) and which can be watched through the trace_pipe file. Finally, the function returns XDP_PASS. XDP_PASS indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "20.02.2023"}, {"filePath": "experiment01-tailgrow/xdp_prog_kern4.c", "funcName": "_xdp_test1", "startLine": 8, "endLine": 22, "description": "The fucntion _xdp_test1 stores two bytes from the end of the packet data and passes the packet to the next layer of network stack for processing.\n The function _xdp_test1 takes ctx of type struct xdp_md as input. struct xdp_md is the metadata for the XDP packet. \n The void pointer data points to the start of the packet.\n An integer variable len is initialized with the value 12.\n An unsigned integer variable offset is initialized with the value len - 2.\n It checks if ctx_store_bytes(ctx, offset, data, 2, 0) < 0, it returns XDP_ABORTED, which means it will drop the packet with a tracepoint exception.\n Else, the function returns XDP_PASS, which indicates that the packet should be forwarded to the normal network stack for further processing.\n The ctx_store_bytes helper function stores the first two bytes of the packet data at an offset of 10 bytes from the end of the packet data. \n Using ctx_store_bytes(ctx, offset, data, 2, 0) < 0, it is checking the bound condition that whether it is exceeding the size of the packet or not. \n If the return value is negative then error has occured, else it returns the number of bytes written to the packet.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "21.02.2023"}, {"filePath": "packet-solutions/xdp_prog_kern_02.c", "funcName": "xdp_patch_ports_func", "startLine": 21, "endLine": 64, "description": "The function will decrease by one destination port number in any TCP or UDP packet.\n The function xdp_patch_ports_func takes ctx of type struct xdp_md as input. struct xdp_md is the metadata for the XDP packet. \n Two pointers data and data_end points to the start and end of the XDP packet data respectively.\n The packet contents are in between ctx->data and ctx->data_end.\n eth is a pointer to an element of a structure ethhdr, ethhdr is an Ethernet frame header defined in <linux/if_ether.h>\n parse_ethhdr(&nh, data_end, ð) takes the current parsing position nh, the pos of packet end, and the eth as input and returns the packet type ID (or EtherType) which is stored in an integer variable eth_type.\n If eth_type < 0, action is set to XDP_ABORTED and a call is made to xdp_stats_record_action(ctx, action).\n If eth_type == bpf_htons(ETH_P_IP) i.e. eth_type == IPv4, it will call parse_iphdr(&nh, data_end, &iphdr) function which returns the type of packet (TCP or UDP) by parsing the packet header. The return value will be stored in a variable called ip_type.\n Else if eth_type == bpf_htons(ETH_P_IPV6) i.e. eth_type == IPv6, it will call parse_iphdr(&nh, data_end, &iphdr) function which returns the type of packet (TCP or UDP) by parsing the packet header. The return value will be stored in a variable called ip_type.\n Else a call is made to xdp_stats_record_action(ctx, action) where action is set to XDP_PASS.\n If the packet is a UDP packet, the packet header is parsed and xdp_stats_record_action(ctx, action) is called where action is set to XDP_ABORTED.\n Then it will decrease by one destination port number in UDP packet.\n Else if the packet is a TCP packet, the packet header is parsed and xdp_stats_record_action(ctx, action) is called where action is set to XDP_ABORTED.\n Then it will decrease by one destination port number in TCP packet.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "21.02.2023"}, {"filePath": "packet-solutions/xdp_prog_kern_02.c", "funcName": "xdp_vlan_swap_func", "startLine": 71, "endLine": 92, "description": "The function either removes the outermost VLAN tag if exists or add back a missing VLAN tag.\n The function xdp_vlan_swap_func takes ctx of type struct xdp_md as input. struct xdp_md is the metadata for the XDP packet. \n Two pointers data and data_end points to the start and end of the XDP packet data respectively.\n The packet contents are in between ctx->data and ctx->data_end.\n The variable nh is of type struct hdr_cursor. struct hdr_cursor stores a void pointer pos, which is used to keep track of the current parsing position.\n nh.pos initially points to the start of the packet data.\n eth is a pointer to an element of a structure ethhdr, ethhdr is an Ethernet frame header defined in <linux/if_ether.h>\n parse_ethhdr(&nh, data_end, ð) takes the current parsing position nh, the pos of packet end, and the eth as input and returns the packet type ID (or EtherType) which is stored in an integer variable nh_type.\n If nh_type < 0, it returns XDP_PASS, which indicates that the packet should be forwarded to the normal network stack for further processing.\n Else if proto_is_vlan(eth->h_proto) is true, it calls vlan_tag_pop(ctx, eth) function which removes the VLAN tag from the ethernet header.\n proto_is_vlan(eth->h_proto) function takes the ethernet frame's packet type ID field as input and checks if eth->h_proto is equal to the 16-bit number in the network byte order of ETH_P_8021Q (802.1Q VLAN Extended Header) or ETH_P_8021AD (802.1ad Service VLAN).\n Else a VLAN tag is added with a value 1 by calling vlan_tag_push(ctx, eth, 1) function.\n Finally, the function returns XDP_PASS, which indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "21.02.2023"}, {"filePath": "packet-solutions/xdp_prog_kern_02.c", "funcName": "xdp_pass_func", "startLine": 95, "endLine": 98, "description": "The function xdp_pass_func takes ctx of type struct xdp_md as input. struct xdp_md is the metadata for XDP packet.\n The function returns XDP_PASS, which indicates that the packet should be forwarded to the normal network stack for further processing.", "author": "Utkalika Satapathy", "authorEmail": "[email protected]", "date": "21.02.2023"}]}