Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
101 lines (85 sloc) 2.3 KB
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include "bpf_helpers.h"
#include "bpf_endian.h"
// The parsing helper functions from the packet01 lesson have moved here
#include "../common/parsing_helpers.h"
#include "../common/rewrite_helpers.h"
/* Defines xdp_stats_map */
#include "../common/xdp_stats_kern_user.h"
#include "../common/xdp_stats_kern.h"
/*
* Solution to the assignment 1 in lesson packet02
*/
SEC("xdp_patch_ports")
int xdp_patch_ports_func(struct xdp_md *ctx)
{
int action = XDP_PASS;
int eth_type, ip_type;
struct ethhdr *eth;
struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr;
struct tcphdr *tcphdr;
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct hdr_cursor nh = { .pos = data };
eth_type = parse_ethhdr(&nh, data_end, &eth);
if (eth_type < 0) {
action = XDP_ABORTED;
goto out;
}
if (eth_type == bpf_htons(ETH_P_IP)) {
ip_type = parse_iphdr(&nh, data_end, &iphdr);
} else if (eth_type == bpf_htons(ETH_P_IPV6)) {
ip_type = parse_ip6hdr(&nh, data_end, &ipv6hdr);
} else {
goto out;
}
if (ip_type == IPPROTO_UDP) {
if (parse_udphdr(&nh, data_end, &udphdr) < 0) {
action = XDP_ABORTED;
goto out;
}
udphdr->dest = bpf_htons(bpf_ntohs(udphdr->dest) - 1);
} else if (ip_type == IPPROTO_TCP) {
if (parse_tcphdr(&nh, data_end, &tcphdr) < 0) {
action = XDP_ABORTED;
goto out;
}
tcphdr->dest = bpf_htons(bpf_ntohs(tcphdr->dest) - 1);
}
out:
return xdp_stats_record_action(ctx, action);
}
/*
* Solution to the assignments 2 and 3 in lesson packet02: Will pop outermost
* VLAN tag if it exists, otherwise push a new one with ID 1
*/
SEC("xdp_vlan_swap")
int xdp_vlan_swap_func(struct xdp_md *ctx)
{
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
/* These keep track of the next header type and iterator pointer */
struct hdr_cursor nh;
int nh_type;
nh.pos = data;
struct ethhdr *eth;
nh_type = parse_ethhdr(&nh, data_end, &eth);
if (nh_type < 0)
return XDP_PASS;
if (proto_is_vlan(eth->h_proto))
vlan_tag_pop(ctx, eth);
else
vlan_tag_push(ctx, eth, 1);
return XDP_PASS;
}
SEC("xdp_pass")
int xdp_pass_func(struct xdp_md *ctx)
{
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
You can’t perform that action at this time.