if (ifindex > -1) { if (bpf_xdp_query_id(ifindex, xdp_flags, &curr_prog_id)) {
printf("bpf_xdp_query_id failed\n"); exit(1);
} if (prog_id == curr_prog_id)
bpf_xdp_detach(ifindex, xdp_flags, NULL); elseif (!curr_prog_id)
printf("couldn't find a prog id on a given iface\n"); else
printf("program on interface changed, not removing\n");
} exit(0);
}
while (!kill_after_s || time(NULL) - started_at <= kill_after_s) {
sleep(STATS_INTERVAL_S);
for (proto = 0; proto < nr_protos; proto++) {
__u64 sum = 0;
assert(bpf_map_lookup_elem(rxcnt_map_fd, &proto,
values) == 0); for (i = 0; i < nr_cpus; i++)
sum += (values[i] - prev[proto][i]);
if (sum)
printf("proto %u: sum:%10llu pkts, rate:%10llu pkts/s\n",
proto, sum, sum / STATS_INTERVAL_S);
memcpy(prev[proto], values, sizeof(values));
}
}
}
staticvoid usage(constchar *cmd)
{
printf("Start a XDP prog which encapsulates incoming packets\n" "in an IPv4/v6 header and XDP_TX it out. The dst <VIP:PORT>\n" "is used to select packets to encapsulate\n\n");
printf("Usage: %s [...]\n", cmd);
printf(" -i <ifname|ifindex> Interface\n");
printf(" -a <vip-service-address> IPv4 or IPv6\n");
printf(" -p <vip-service-port> A port range (e.g. 433-444) is also allowed\n");
printf(" -s <source-ip> Used in the IPTunnel header\n");
printf(" -d <dest-ip> Used in the IPTunnel header\n");
printf(" -m <dest-MAC> Used in sending the IP Tunneled pkt\n");
printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n");
printf(" -P <IP-Protocol> Default is TCP\n");
printf(" -S use skb-mode\n");
printf(" -N enforce native mode\n");
printf(" -F Force loading the XDP prog\n");
printf(" -h Display this help\n");
}
family = parse_ipstr(optarg, v6); if (family == AF_UNSPEC) return1; if (tnl.family == AF_UNSPEC) {
tnl.family = family;
} elseif (tnl.family != family) {
fprintf(stderr, "The IP version of the src and dst addresses used in the IP encapsulation does not match\n"); return1;
} break; case'm': if (!ether_aton_r(optarg,
(struct ether_addr *)tnl.dmac)) {
fprintf(stderr, "Invalid mac address:%s\n",
optarg); return1;
} break; case'T':
kill_after_s = atoi(optarg); break; case'S':
xdp_flags |= XDP_FLAGS_SKB_MODE; break; case'N': /* default, set below */ break; case'F':
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST; break; default:
usage(argv[0]); return1;
}
opt_flags[opt] = 0;
}
if (!(xdp_flags & XDP_FLAGS_SKB_MODE))
xdp_flags |= XDP_FLAGS_DRV_MODE;
for (i = 0; i < strlen(optstr); i++) { if (opt_flags[(unsignedint)optstr[i]]) {
fprintf(stderr, "Missing argument -%c\n", optstr[i]);
usage(argv[0]); return1;
}
}
if (!ifindex) {
fprintf(stderr, "Invalid ifname\n"); return1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.