Merge branch 'master' into net-next
This commit is contained in:
commit
39afc4b08e
21
bridge/fdb.c
21
bridge/fdb.c
|
|
@ -27,7 +27,7 @@
|
||||||
#include "rt_names.h"
|
#include "rt_names.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static unsigned int filter_index;
|
static unsigned int filter_index, filter_vlan;
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
|
|
@ -35,7 +35,7 @@ static void usage(void)
|
||||||
" [ self ] [ master ] [ use ] [ router ]\n"
|
" [ self ] [ master ] [ use ] [ router ]\n"
|
||||||
" [ local | static | dynamic ] [ dst IPADDR ] [ vlan VID ]\n"
|
" [ local | static | dynamic ] [ dst IPADDR ] [ vlan VID ]\n"
|
||||||
" [ port PORT] [ vni VNI ] [ via DEV ]\n");
|
" [ port PORT] [ vni VNI ] [ via DEV ]\n");
|
||||||
fprintf(stderr, " bridge fdb [ show [ br BRDEV ] [ brport DEV ] ]\n");
|
fprintf(stderr, " bridge fdb [ show [ br BRDEV ] [ brport DEV ] [ vlan VID ] ]\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,6 +65,7 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
struct ndmsg *r = NLMSG_DATA(n);
|
struct ndmsg *r = NLMSG_DATA(n);
|
||||||
int len = n->nlmsg_len;
|
int len = n->nlmsg_len;
|
||||||
struct rtattr *tb[NDA_MAX+1];
|
struct rtattr *tb[NDA_MAX+1];
|
||||||
|
__u16 vid = 0;
|
||||||
|
|
||||||
if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
|
if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
|
||||||
fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
|
fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
|
||||||
|
|
@ -88,6 +89,12 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
|
parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
|
||||||
n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
||||||
|
|
||||||
|
if (tb[NDA_VLAN])
|
||||||
|
vid = rta_getattr_u16(tb[NDA_VLAN]);
|
||||||
|
|
||||||
|
if (filter_vlan && filter_vlan != vid)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (n->nlmsg_type == RTM_DELNEIGH)
|
if (n->nlmsg_type == RTM_DELNEIGH)
|
||||||
fprintf(fp, "Deleted ");
|
fprintf(fp, "Deleted ");
|
||||||
|
|
||||||
|
|
@ -115,11 +122,8 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
RTA_DATA(tb[NDA_DST])));
|
RTA_DATA(tb[NDA_DST])));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[NDA_VLAN]) {
|
if (vid)
|
||||||
__u16 vid = rta_getattr_u16(tb[NDA_VLAN]);
|
|
||||||
|
|
||||||
fprintf(fp, "vlan %hu ", vid);
|
fprintf(fp, "vlan %hu ", vid);
|
||||||
}
|
|
||||||
|
|
||||||
if (tb[NDA_PORT])
|
if (tb[NDA_PORT])
|
||||||
fprintf(fp, "port %d ", ntohs(rta_getattr_u16(tb[NDA_PORT])));
|
fprintf(fp, "port %d ", ntohs(rta_getattr_u16(tb[NDA_PORT])));
|
||||||
|
|
@ -190,6 +194,11 @@ static int fdb_show(int argc, char **argv)
|
||||||
} else if (strcmp(*argv, "br") == 0) {
|
} else if (strcmp(*argv, "br") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
br = *argv;
|
br = *argv;
|
||||||
|
} else if (strcmp(*argv, "vlan") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (filter_vlan)
|
||||||
|
duparg("vlan", *argv);
|
||||||
|
filter_vlan = atoi(*argv);
|
||||||
} else {
|
} else {
|
||||||
if (matches(*argv, "help") == 0)
|
if (matches(*argv, "help") == 0)
|
||||||
usage();
|
usage();
|
||||||
|
|
|
||||||
11
bridge/mdb.c
11
bridge/mdb.c
|
|
@ -24,12 +24,12 @@
|
||||||
((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct br_port_msg))))
|
((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct br_port_msg))))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned int filter_index;
|
static unsigned int filter_index, filter_vlan;
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [permanent | temp] [vid VID]\n");
|
fprintf(stderr, "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [permanent | temp] [vid VID]\n");
|
||||||
fprintf(stderr, " bridge mdb {show} [ dev DEV ]\n");
|
fprintf(stderr, " bridge mdb {show} [ dev DEV ] [ vid VID ]\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,6 +92,8 @@ static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e,
|
||||||
const void *src;
|
const void *src;
|
||||||
int af;
|
int af;
|
||||||
|
|
||||||
|
if (filter_vlan && e->vid != filter_vlan)
|
||||||
|
return;
|
||||||
af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
|
af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
|
||||||
src = af == AF_INET ? (const void *)&e->addr.u.ip4 :
|
src = af == AF_INET ? (const void *)&e->addr.u.ip4 :
|
||||||
(const void *)&e->addr.u.ip6;
|
(const void *)&e->addr.u.ip6;
|
||||||
|
|
@ -195,6 +197,11 @@ static int mdb_show(int argc, char **argv)
|
||||||
if (filter_dev)
|
if (filter_dev)
|
||||||
duparg("dev", *argv);
|
duparg("dev", *argv);
|
||||||
filter_dev = *argv;
|
filter_dev = *argv;
|
||||||
|
} else if (strcmp(*argv, "vid") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (filter_vlan)
|
||||||
|
duparg("vid", *argv);
|
||||||
|
filter_vlan = atoi(*argv);
|
||||||
}
|
}
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,13 @@
|
||||||
#include "br_common.h"
|
#include "br_common.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static unsigned int filter_index;
|
static unsigned int filter_index, filter_vlan;
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
|
fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
|
||||||
fprintf(stderr, " [ self ] [ master ]\n");
|
fprintf(stderr, " [ self ] [ master ]\n");
|
||||||
fprintf(stderr, " bridge vlan { show } [ dev DEV ]\n");
|
fprintf(stderr, " bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,6 +138,26 @@ static int vlan_modify(int cmd, int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In order to use this function for both filtering and non-filtering cases
|
||||||
|
* we need to make it a tristate:
|
||||||
|
* return -1 - if filtering we've gone over so don't continue
|
||||||
|
* return 0 - skip entry and continue (applies to range start or to entries
|
||||||
|
* which are less than filter_vlan)
|
||||||
|
* return 1 - print the entry and continue
|
||||||
|
*/
|
||||||
|
static int filter_vlan_check(struct bridge_vlan_info *vinfo)
|
||||||
|
{
|
||||||
|
/* if we're filtering we should stop on the first greater entry */
|
||||||
|
if (filter_vlan && vinfo->vid > filter_vlan &&
|
||||||
|
!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
|
||||||
|
return -1;
|
||||||
|
if ((vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
|
||||||
|
vinfo->vid < filter_vlan)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int print_vlan(const struct sockaddr_nl *who,
|
static int print_vlan(const struct sockaddr_nl *who,
|
||||||
struct nlmsghdr *n,
|
struct nlmsghdr *n,
|
||||||
void *arg)
|
void *arg)
|
||||||
|
|
@ -169,26 +189,40 @@ static int print_vlan(const struct sockaddr_nl *who,
|
||||||
|
|
||||||
/* if AF_SPEC isn't there, vlan table is not preset for this port */
|
/* if AF_SPEC isn't there, vlan table is not preset for this port */
|
||||||
if (!tb[IFLA_AF_SPEC]) {
|
if (!tb[IFLA_AF_SPEC]) {
|
||||||
fprintf(fp, "%s\tNone\n", ll_index_to_name(ifm->ifi_index));
|
if (!filter_vlan)
|
||||||
|
fprintf(fp, "%s\tNone\n",
|
||||||
|
ll_index_to_name(ifm->ifi_index));
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
struct rtattr *i, *list = tb[IFLA_AF_SPEC];
|
struct rtattr *i, *list = tb[IFLA_AF_SPEC];
|
||||||
int rem = RTA_PAYLOAD(list);
|
int rem = RTA_PAYLOAD(list);
|
||||||
|
__u16 last_vid_start = 0;
|
||||||
|
|
||||||
fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
|
if (!filter_vlan)
|
||||||
|
fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
|
||||||
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
||||||
struct bridge_vlan_info *vinfo;
|
struct bridge_vlan_info *vinfo;
|
||||||
|
int vcheck_ret;
|
||||||
|
|
||||||
if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
|
if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vinfo = RTA_DATA(i);
|
vinfo = RTA_DATA(i);
|
||||||
if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)
|
|
||||||
fprintf(fp, "-%hu", vinfo->vid);
|
if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
|
||||||
else
|
last_vid_start = vinfo->vid;
|
||||||
fprintf(fp, "\t %hu", vinfo->vid);
|
vcheck_ret = filter_vlan_check(vinfo);
|
||||||
if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
|
if (vcheck_ret == -1)
|
||||||
|
break;
|
||||||
|
else if (vcheck_ret == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (filter_vlan)
|
||||||
|
fprintf(fp, "%s",
|
||||||
|
ll_index_to_name(ifm->ifi_index));
|
||||||
|
fprintf(fp, "\t %hu", last_vid_start);
|
||||||
|
if (last_vid_start != vinfo->vid)
|
||||||
|
fprintf(fp, "-%hu", vinfo->vid);
|
||||||
if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
|
if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
|
||||||
fprintf(fp, " PVID");
|
fprintf(fp, " PVID");
|
||||||
if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
|
if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
|
||||||
|
|
@ -196,7 +230,8 @@ static int print_vlan(const struct sockaddr_nl *who,
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(fp, "\n");
|
if (!filter_vlan)
|
||||||
|
fprintf(fp, "\n");
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -211,6 +246,11 @@ static int vlan_show(int argc, char **argv)
|
||||||
if (filter_dev)
|
if (filter_dev)
|
||||||
duparg("dev", *argv);
|
duparg("dev", *argv);
|
||||||
filter_dev = *argv;
|
filter_dev = *argv;
|
||||||
|
} else if (strcmp(*argv, "vid") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (filter_vlan)
|
||||||
|
duparg("vid", *argv);
|
||||||
|
filter_vlan = atoi(*argv);
|
||||||
}
|
}
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,14 @@
|
||||||
*/
|
*/
|
||||||
#define JMP_MAP_ID 0xabccba
|
#define JMP_MAP_ID 0xabccba
|
||||||
|
|
||||||
BPF_PROG_ARRAY(jmp_tc, JMP_MAP_ID, PIN_OBJECT_NS, 1);
|
struct bpf_elf_map __section_maps jmp_tc = {
|
||||||
|
.type = BPF_MAP_TYPE_PROG_ARRAY,
|
||||||
|
.id = JMP_MAP_ID,
|
||||||
|
.size_key = sizeof(uint32_t),
|
||||||
|
.size_value = sizeof(uint32_t),
|
||||||
|
.pinning = PIN_OBJECT_NS,
|
||||||
|
.max_elem = 1,
|
||||||
|
};
|
||||||
|
|
||||||
__section_tail(JMP_MAP_ID, 0)
|
__section_tail(JMP_MAP_ID, 0)
|
||||||
int cls_loop(struct __sk_buff *skb)
|
int cls_loop(struct __sk_buff *skb)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,13 @@
|
||||||
* [...]
|
* [...]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BPF_PROG_ARRAY(jmp_tc, 0, PIN_GLOBAL_NS, 1);
|
struct bpf_elf_map __section_maps jmp_tc = {
|
||||||
|
.type = BPF_MAP_TYPE_PROG_ARRAY,
|
||||||
|
.size_key = sizeof(uint32_t),
|
||||||
|
.size_value = sizeof(uint32_t),
|
||||||
|
.pinning = PIN_GLOBAL_NS,
|
||||||
|
.max_elem = 1,
|
||||||
|
};
|
||||||
|
|
||||||
__section("aaa")
|
__section("aaa")
|
||||||
int cls_aaa(struct __sk_buff *skb)
|
int cls_aaa(struct __sk_buff *skb)
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,7 @@ struct bpf_elf_map __section("maps") map_proto = {
|
||||||
.size_key = sizeof(uint8_t),
|
.size_key = sizeof(uint8_t),
|
||||||
.size_value = sizeof(struct count_tuple),
|
.size_value = sizeof(struct count_tuple),
|
||||||
.max_elem = 256,
|
.max_elem = 256,
|
||||||
|
.flags = BPF_F_NO_PREALLOC,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bpf_elf_map __section("maps") map_queue = {
|
struct bpf_elf_map __section("maps") map_queue = {
|
||||||
|
|
@ -200,6 +201,7 @@ struct bpf_elf_map __section("maps") map_queue = {
|
||||||
.size_key = sizeof(uint32_t),
|
.size_key = sizeof(uint32_t),
|
||||||
.size_value = sizeof(struct count_queue),
|
.size_value = sizeof(struct count_queue),
|
||||||
.max_elem = 1024,
|
.max_elem = 1024,
|
||||||
|
.flags = BPF_F_NO_PREALLOC,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bpf_elf_map __section("maps") map_drops = {
|
struct bpf_elf_map __section("maps") map_drops = {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,13 @@
|
||||||
* instance is being created.
|
* instance is being created.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BPF_ARRAY4(map_sh, 0, PIN_OBJECT_NS, 1); /* or PIN_GLOBAL_NS, or PIN_NONE */
|
struct bpf_elf_map __section_maps map_sh = {
|
||||||
|
.type = BPF_MAP_TYPE_ARRAY,
|
||||||
|
.size_key = sizeof(uint32_t),
|
||||||
|
.size_value = sizeof(uint32_t),
|
||||||
|
.pinning = PIN_OBJECT_NS, /* or PIN_GLOBAL_NS, or PIN_NONE */
|
||||||
|
.max_elem = 1,
|
||||||
|
};
|
||||||
|
|
||||||
__section("egress")
|
__section("egress")
|
||||||
int emain(struct __sk_buff *skb)
|
int emain(struct __sk_buff *skb)
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,31 @@
|
||||||
* classifier behaviour.
|
* classifier behaviour.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BPF_PROG_ARRAY(jmp_tc, FOO, PIN_OBJECT_NS, MAX_JMP_SIZE);
|
struct bpf_elf_map __section_maps jmp_tc = {
|
||||||
BPF_PROG_ARRAY(jmp_ex, BAR, PIN_OBJECT_NS, 1);
|
.type = BPF_MAP_TYPE_PROG_ARRAY,
|
||||||
|
.id = FOO,
|
||||||
|
.size_key = sizeof(uint32_t),
|
||||||
|
.size_value = sizeof(uint32_t),
|
||||||
|
.pinning = PIN_OBJECT_NS,
|
||||||
|
.max_elem = MAX_JMP_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
BPF_ARRAY4(map_sh, 0, PIN_OBJECT_NS, 1);
|
struct bpf_elf_map __section_maps jmp_ex = {
|
||||||
|
.type = BPF_MAP_TYPE_PROG_ARRAY,
|
||||||
|
.id = BAR,
|
||||||
|
.size_key = sizeof(uint32_t),
|
||||||
|
.size_value = sizeof(uint32_t),
|
||||||
|
.pinning = PIN_OBJECT_NS,
|
||||||
|
.max_elem = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpf_elf_map __section_maps map_sh = {
|
||||||
|
.type = BPF_MAP_TYPE_ARRAY,
|
||||||
|
.size_key = sizeof(uint32_t),
|
||||||
|
.size_value = sizeof(uint32_t),
|
||||||
|
.pinning = PIN_OBJECT_NS,
|
||||||
|
.max_elem = 1,
|
||||||
|
};
|
||||||
|
|
||||||
__section_tail(FOO, ENTRY_0)
|
__section_tail(FOO, ENTRY_0)
|
||||||
int cls_case1(struct __sk_buff *skb)
|
int cls_case1(struct __sk_buff *skb)
|
||||||
|
|
|
||||||
|
|
@ -99,51 +99,6 @@
|
||||||
char ____license[] __section_license = NAME
|
char ____license[] __section_license = NAME
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __BPF_MAP
|
|
||||||
# define __BPF_MAP(NAME, TYPE, ID, SIZE_KEY, SIZE_VALUE, PIN, MAX_ELEM) \
|
|
||||||
struct bpf_elf_map __section_maps NAME = { \
|
|
||||||
.type = (TYPE), \
|
|
||||||
.id = (ID), \
|
|
||||||
.size_key = (SIZE_KEY), \
|
|
||||||
.size_value = (SIZE_VALUE), \
|
|
||||||
.pinning = (PIN), \
|
|
||||||
.max_elem = (MAX_ELEM), \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BPF_HASH
|
|
||||||
# define BPF_HASH(NAME, ID, SIZE_KEY, SIZE_VALUE, PIN, MAX_ELEM) \
|
|
||||||
__BPF_MAP(NAME, BPF_MAP_TYPE_HASH, ID, SIZE_KEY, SIZE_VALUE, \
|
|
||||||
PIN, MAX_ELEM)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BPF_ARRAY
|
|
||||||
# define BPF_ARRAY(NAME, ID, SIZE_VALUE, PIN, MAX_ELEM) \
|
|
||||||
__BPF_MAP(NAME, BPF_MAP_TYPE_ARRAY, ID, sizeof(uint32_t), \
|
|
||||||
SIZE_VALUE, PIN, MAX_ELEM)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BPF_ARRAY2
|
|
||||||
# define BPF_ARRAY2(NAME, ID, PIN, MAX_ELEM) \
|
|
||||||
BPF_ARRAY(NAME, ID, sizeof(uint16_t), PIN, MAX_ELEM)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BPF_ARRAY4
|
|
||||||
# define BPF_ARRAY4(NAME, ID, PIN, MAX_ELEM) \
|
|
||||||
BPF_ARRAY(NAME, ID, sizeof(uint32_t), PIN, MAX_ELEM)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BPF_ARRAY8
|
|
||||||
# define BPF_ARRAY8(NAME, ID, PIN, MAX_ELEM) \
|
|
||||||
BPF_ARRAY(NAME, ID, sizeof(uint64_t), PIN, MAX_ELEM)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BPF_PROG_ARRAY
|
|
||||||
# define BPF_PROG_ARRAY(NAME, ID, PIN, MAX_ELEM) \
|
|
||||||
__BPF_MAP(NAME, BPF_MAP_TYPE_PROG_ARRAY, ID, sizeof(uint32_t), \
|
|
||||||
sizeof(uint32_t), PIN, MAX_ELEM)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Classifier helper */
|
/** Classifier helper */
|
||||||
|
|
||||||
#ifndef BPF_H_DEFAULT
|
#ifndef BPF_H_DEFAULT
|
||||||
|
|
@ -212,6 +167,8 @@ static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
|
||||||
uint32_t from, uint32_t to, uint32_t flags);
|
uint32_t from, uint32_t to, uint32_t flags);
|
||||||
static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
|
static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
|
||||||
uint32_t from, uint32_t to, uint32_t flags);
|
uint32_t from, uint32_t to, uint32_t flags);
|
||||||
|
static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
|
||||||
|
const void *to, uint32_t to_size, uint32_t seed);
|
||||||
|
|
||||||
/* Packet vlan encap/decap */
|
/* Packet vlan encap/decap */
|
||||||
static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
|
static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
|
||||||
|
|
@ -225,6 +182,11 @@ static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
|
||||||
const struct bpf_tunnel_key *from, uint32_t size,
|
const struct bpf_tunnel_key *from, uint32_t size,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
|
|
||||||
|
static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
|
||||||
|
void *to, uint32_t size);
|
||||||
|
static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
|
||||||
|
const void *from, uint32_t size);
|
||||||
|
|
||||||
/** LLVM built-ins, mem*() routines work for constant size */
|
/** LLVM built-ins, mem*() routines work for constant size */
|
||||||
|
|
||||||
#ifndef lock_xadd
|
#ifndef lock_xadd
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ struct bpf_elf_map {
|
||||||
__u32 size_key;
|
__u32 size_key;
|
||||||
__u32 size_value;
|
__u32 size_value;
|
||||||
__u32 max_elem;
|
__u32 max_elem;
|
||||||
|
__u32 flags;
|
||||||
__u32 id;
|
__u32 id;
|
||||||
__u32 pinning;
|
__u32 pinning;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
|
||||||
* this kernel.
|
* this kernel.
|
||||||
*/
|
*/
|
||||||
tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
|
tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
|
||||||
vf[IFLA_VF_TX_RATE]->rta_len);
|
vf[IFLA_VF_TX_RATE]->rta_len);
|
||||||
|
|
||||||
if (tmp->rta_type != IFLA_VF_SPOOFCHK)
|
if (tmp->rta_type != IFLA_VF_SPOOFCHK)
|
||||||
vf_spoofchk = NULL;
|
vf_spoofchk = NULL;
|
||||||
|
|
@ -338,7 +338,7 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
|
||||||
* this kernel.
|
* this kernel.
|
||||||
*/
|
*/
|
||||||
tmp = (struct rtattr *)((char *)vf[IFLA_VF_SPOOFCHK] +
|
tmp = (struct rtattr *)((char *)vf[IFLA_VF_SPOOFCHK] +
|
||||||
vf[IFLA_VF_SPOOFCHK]->rta_len);
|
vf[IFLA_VF_SPOOFCHK]->rta_len);
|
||||||
|
|
||||||
if (tmp->rta_type != IFLA_VF_LINK_STATE)
|
if (tmp->rta_type != IFLA_VF_LINK_STATE)
|
||||||
vf_linkstate = NULL;
|
vf_linkstate = NULL;
|
||||||
|
|
@ -349,7 +349,7 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
|
||||||
|
|
||||||
fprintf(fp, "%s vf %d MAC %s", _SL_, vf_mac->vf,
|
fprintf(fp, "%s vf %d MAC %s", _SL_, vf_mac->vf,
|
||||||
ll_addr_n2a((unsigned char *)&vf_mac->mac,
|
ll_addr_n2a((unsigned char *)&vf_mac->mac,
|
||||||
ETH_ALEN, 0, b1, sizeof(b1)));
|
ETH_ALEN, 0, b1, sizeof(b1)));
|
||||||
if (vf_vlan->vlan)
|
if (vf_vlan->vlan)
|
||||||
fprintf(fp, ", vlan %d", vf_vlan->vlan);
|
fprintf(fp, ", vlan %d", vf_vlan->vlan);
|
||||||
if (vf_vlan->qos)
|
if (vf_vlan->qos)
|
||||||
|
|
@ -380,6 +380,13 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
|
||||||
else
|
else
|
||||||
fprintf(fp, ", link-state disable");
|
fprintf(fp, ", link-state disable");
|
||||||
}
|
}
|
||||||
|
if (vf[IFLA_VF_TRUST]) {
|
||||||
|
struct ifla_vf_trust *vf_trust = RTA_DATA(vf[IFLA_VF_TRUST]);
|
||||||
|
|
||||||
|
if (vf_trust->setting != -1)
|
||||||
|
fprintf(fp, ", trust %s",
|
||||||
|
vf_trust->setting ? "on" : "off");
|
||||||
|
}
|
||||||
if (vf[IFLA_VF_STATS] && show_stats)
|
if (vf[IFLA_VF_STATS] && show_stats)
|
||||||
print_vf_stats64(fp, vf[IFLA_VF_STATS]);
|
print_vf_stats64(fp, vf[IFLA_VF_STATS]);
|
||||||
}
|
}
|
||||||
|
|
@ -782,7 +789,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
|
||||||
|
|
||||||
fprintf(fp, "%d: ", ifi->ifi_index);
|
fprintf(fp, "%d: ", ifi->ifi_index);
|
||||||
color_fprintf(fp, COLOR_IFNAME, "%s",
|
color_fprintf(fp, COLOR_IFNAME, "%s",
|
||||||
tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
|
tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
|
||||||
|
|
||||||
if (tb[IFLA_LINK]) {
|
if (tb[IFLA_LINK]) {
|
||||||
SPRINT_BUF(b1);
|
SPRINT_BUF(b1);
|
||||||
|
|
@ -813,22 +820,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
|
||||||
fprintf(fp, "master %s ", ll_idx_n2a(*(int *)RTA_DATA(tb[IFLA_MASTER]), b1));
|
fprintf(fp, "master %s ", ll_idx_n2a(*(int *)RTA_DATA(tb[IFLA_MASTER]), b1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[IFLA_PHYS_PORT_ID]) {
|
|
||||||
SPRINT_BUF(b1);
|
|
||||||
fprintf(fp, "portid %s ",
|
|
||||||
hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
|
|
||||||
RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
|
|
||||||
b1, sizeof(b1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tb[IFLA_PHYS_SWITCH_ID]) {
|
|
||||||
SPRINT_BUF(b1);
|
|
||||||
fprintf(fp, "switchid %s ",
|
|
||||||
hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
|
|
||||||
RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
|
|
||||||
b1, sizeof(b1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tb[IFLA_OPERSTATE])
|
if (tb[IFLA_OPERSTATE])
|
||||||
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
|
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
|
||||||
|
|
||||||
|
|
@ -852,10 +843,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
|
||||||
|
|
||||||
if (tb[IFLA_ADDRESS]) {
|
if (tb[IFLA_ADDRESS]) {
|
||||||
color_fprintf(fp, COLOR_MAC, "%s",
|
color_fprintf(fp, COLOR_MAC, "%s",
|
||||||
ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
|
ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
|
||||||
RTA_PAYLOAD(tb[IFLA_ADDRESS]),
|
RTA_PAYLOAD(tb[IFLA_ADDRESS]),
|
||||||
ifi->ifi_type,
|
ifi->ifi_type,
|
||||||
b1, sizeof(b1)));
|
b1, sizeof(b1)));
|
||||||
}
|
}
|
||||||
if (tb[IFLA_BROADCAST]) {
|
if (tb[IFLA_BROADCAST]) {
|
||||||
if (ifi->ifi_flags&IFF_POINTOPOINT)
|
if (ifi->ifi_flags&IFF_POINTOPOINT)
|
||||||
|
|
@ -863,10 +854,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
|
||||||
else
|
else
|
||||||
fprintf(fp, " brd ");
|
fprintf(fp, " brd ");
|
||||||
color_fprintf(fp, COLOR_MAC, "%s",
|
color_fprintf(fp, COLOR_MAC, "%s",
|
||||||
ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
|
ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
|
||||||
RTA_PAYLOAD(tb[IFLA_BROADCAST]),
|
RTA_PAYLOAD(tb[IFLA_BROADCAST]),
|
||||||
ifi->ifi_type,
|
ifi->ifi_type,
|
||||||
b1, sizeof(b1)));
|
b1, sizeof(b1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -884,15 +875,46 @@ int print_linkinfo(const struct sockaddr_nl *who,
|
||||||
fprintf(fp, " protodown on ");
|
fprintf(fp, " protodown on ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[IFLA_PROMISCUITY] && show_details)
|
if (show_details) {
|
||||||
fprintf(fp, " promiscuity %u ",
|
if (tb[IFLA_PROMISCUITY])
|
||||||
*(int *)RTA_DATA(tb[IFLA_PROMISCUITY]));
|
fprintf(fp, " promiscuity %u ",
|
||||||
|
*(int *)RTA_DATA(tb[IFLA_PROMISCUITY]));
|
||||||
|
|
||||||
if (tb[IFLA_LINKINFO] && show_details)
|
if (tb[IFLA_LINKINFO])
|
||||||
print_linktype(fp, tb[IFLA_LINKINFO]);
|
print_linktype(fp, tb[IFLA_LINKINFO]);
|
||||||
|
|
||||||
|
if (do_link && tb[IFLA_AF_SPEC])
|
||||||
|
print_af_spec(fp, tb[IFLA_AF_SPEC]);
|
||||||
|
|
||||||
|
if (tb[IFLA_NUM_TX_QUEUES])
|
||||||
|
fprintf(fp, "numtxqueues %u ",
|
||||||
|
rta_getattr_u32(tb[IFLA_NUM_TX_QUEUES]));
|
||||||
|
|
||||||
|
if (tb[IFLA_NUM_RX_QUEUES])
|
||||||
|
fprintf(fp, "numrxqueues %u ",
|
||||||
|
rta_getattr_u32(tb[IFLA_NUM_RX_QUEUES]));
|
||||||
|
|
||||||
|
if (tb[IFLA_PHYS_PORT_NAME])
|
||||||
|
fprintf(fp, "portname %s ",
|
||||||
|
rta_getattr_str(tb[IFLA_PHYS_PORT_NAME]));
|
||||||
|
|
||||||
|
if (tb[IFLA_PHYS_PORT_ID]) {
|
||||||
|
SPRINT_BUF(b1);
|
||||||
|
fprintf(fp, "portid %s ",
|
||||||
|
hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
|
||||||
|
RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
|
||||||
|
b1, sizeof(b1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[IFLA_PHYS_SWITCH_ID]) {
|
||||||
|
SPRINT_BUF(b1);
|
||||||
|
fprintf(fp, "switchid %s ",
|
||||||
|
hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
|
||||||
|
RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
|
||||||
|
b1, sizeof(b1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (do_link && tb[IFLA_AF_SPEC] && show_details)
|
|
||||||
print_af_spec(fp, tb[IFLA_AF_SPEC]);
|
|
||||||
|
|
||||||
if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
|
if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
|
||||||
fprintf(fp, "%s alias %s", _SL_,
|
fprintf(fp, "%s alias %s", _SL_,
|
||||||
|
|
|
||||||
99
tc/tc_bpf.c
99
tc/tc_bpf.c
|
|
@ -20,6 +20,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef HAVE_ELF
|
#ifdef HAVE_ELF
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
|
|
@ -184,7 +185,7 @@ static int bpf_ops_parse(int argc, char **argv, struct sock_filter *bpf_ops,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != bpf_len) {
|
if (i != bpf_len) {
|
||||||
fprintf(stderr, "Parsed program length is less than encodedlength parameter!\n");
|
fprintf(stderr, "Parsed program length is less than encoded length parameter!\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
@ -214,6 +215,30 @@ void bpf_print_ops(FILE *f, struct rtattr *bpf_ops, __u16 len)
|
||||||
ops[i].jf, ops[i].k);
|
ops[i].jf, ops[i].k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bpf_map_pin_report(const struct bpf_elf_map *pin,
|
||||||
|
const struct bpf_elf_map *obj)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Map specification differs from pinned file!\n");
|
||||||
|
|
||||||
|
if (obj->type != pin->type)
|
||||||
|
fprintf(stderr, " - Type: %u (obj) != %u (pin)\n",
|
||||||
|
obj->type, pin->type);
|
||||||
|
if (obj->size_key != pin->size_key)
|
||||||
|
fprintf(stderr, " - Size key: %u (obj) != %u (pin)\n",
|
||||||
|
obj->size_key, pin->size_key);
|
||||||
|
if (obj->size_value != pin->size_value)
|
||||||
|
fprintf(stderr, " - Size value: %u (obj) != %u (pin)\n",
|
||||||
|
obj->size_value, pin->size_value);
|
||||||
|
if (obj->max_elem != pin->max_elem)
|
||||||
|
fprintf(stderr, " - Max elems: %u (obj) != %u (pin)\n",
|
||||||
|
obj->max_elem, pin->max_elem);
|
||||||
|
if (obj->flags != pin->flags)
|
||||||
|
fprintf(stderr, " - Flags: %#x (obj) != %#x (pin)\n",
|
||||||
|
obj->flags, pin->flags);
|
||||||
|
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
||||||
int length)
|
int length)
|
||||||
{
|
{
|
||||||
|
|
@ -240,6 +265,8 @@ static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
||||||
tmp.size_value = val;
|
tmp.size_value = val;
|
||||||
else if (sscanf(buff, "max_entries:\t%u", &val) == 1)
|
else if (sscanf(buff, "max_entries:\t%u", &val) == 1)
|
||||||
tmp.max_elem = val;
|
tmp.max_elem = val;
|
||||||
|
else if (sscanf(buff, "map_flags:\t%i", &val) == 1)
|
||||||
|
tmp.flags = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
@ -256,7 +283,7 @@ static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
||||||
if (!memcmp(&tmp, &zero, length))
|
if (!memcmp(&tmp, &zero, length))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fprintf(stderr, "Map specs from pinned file differ!\n");
|
bpf_map_pin_report(&tmp, map);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -735,7 +762,19 @@ bpf_dump_error(struct bpf_elf_ctx *ctx, const char *format, ...)
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
|
||||||
if (ctx->log && ctx->log[0]) {
|
if (ctx->log && ctx->log[0]) {
|
||||||
fprintf(stderr, "%s\n", ctx->log);
|
if (ctx->verbose) {
|
||||||
|
fprintf(stderr, "%s\n", ctx->log);
|
||||||
|
} else {
|
||||||
|
unsigned int off = 0, len = strlen(ctx->log);
|
||||||
|
|
||||||
|
if (len > BPF_MAX_LOG) {
|
||||||
|
off = len - BPF_MAX_LOG;
|
||||||
|
fprintf(stderr, "Skipped %u bytes, use \'verb\' option for the full verbose log.\n[...]\n",
|
||||||
|
off);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s\n", ctx->log + off);
|
||||||
|
}
|
||||||
|
|
||||||
memset(ctx->log, 0, ctx->log_size);
|
memset(ctx->log, 0, ctx->log_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -763,8 +802,9 @@ static int bpf_log_realloc(struct bpf_elf_ctx *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bpf_map_create(enum bpf_map_type type, unsigned int size_key,
|
static int bpf_map_create(enum bpf_map_type type, uint32_t size_key,
|
||||||
unsigned int size_value, unsigned int max_elem)
|
uint32_t size_value, uint32_t max_elem,
|
||||||
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
union bpf_attr attr;
|
union bpf_attr attr;
|
||||||
|
|
||||||
|
|
@ -773,6 +813,7 @@ static int bpf_map_create(enum bpf_map_type type, unsigned int size_key,
|
||||||
attr.key_size = size_key;
|
attr.key_size = size_key;
|
||||||
attr.value_size = size_value;
|
attr.value_size = size_value;
|
||||||
attr.max_entries = max_elem;
|
attr.max_entries = max_elem;
|
||||||
|
attr.map_flags = flags;
|
||||||
|
|
||||||
return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
|
return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
|
||||||
}
|
}
|
||||||
|
|
@ -1055,14 +1096,16 @@ static void bpf_prog_report(int fd, const char *section,
|
||||||
const struct bpf_elf_prog *prog,
|
const struct bpf_elf_prog *prog,
|
||||||
struct bpf_elf_ctx *ctx)
|
struct bpf_elf_ctx *ctx)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Prog section \'%s\' %s%s (%d)!\n", section,
|
unsigned int insns = prog->size / sizeof(struct bpf_insn);
|
||||||
|
|
||||||
|
fprintf(stderr, "\nProg section \'%s\' %s%s (%d)!\n", section,
|
||||||
fd < 0 ? "rejected: " : "loaded",
|
fd < 0 ? "rejected: " : "loaded",
|
||||||
fd < 0 ? strerror(errno) : "",
|
fd < 0 ? strerror(errno) : "",
|
||||||
fd < 0 ? errno : fd);
|
fd < 0 ? errno : fd);
|
||||||
|
|
||||||
fprintf(stderr, " - Type: %u\n", prog->type);
|
fprintf(stderr, " - Type: %u\n", prog->type);
|
||||||
fprintf(stderr, " - Instructions: %zu\n",
|
fprintf(stderr, " - Instructions: %u (%u over limit)\n",
|
||||||
prog->size / sizeof(struct bpf_insn));
|
insns, insns > BPF_MAXINSNS ? insns - BPF_MAXINSNS : 0);
|
||||||
fprintf(stderr, " - License: %s\n\n", prog->license);
|
fprintf(stderr, " - License: %s\n\n", prog->license);
|
||||||
|
|
||||||
bpf_dump_error(ctx, "Verifier analysis:\n\n");
|
bpf_dump_error(ctx, "Verifier analysis:\n\n");
|
||||||
|
|
@ -1112,7 +1155,8 @@ static void bpf_map_report(int fd, const char *name,
|
||||||
fprintf(stderr, " - Pinning: %u\n", map->pinning);
|
fprintf(stderr, " - Pinning: %u\n", map->pinning);
|
||||||
fprintf(stderr, " - Size key: %u\n", map->size_key);
|
fprintf(stderr, " - Size key: %u\n", map->size_key);
|
||||||
fprintf(stderr, " - Size value: %u\n", map->size_value);
|
fprintf(stderr, " - Size value: %u\n", map->size_value);
|
||||||
fprintf(stderr, " - Max elems: %u\n\n", map->max_elem);
|
fprintf(stderr, " - Max elems: %u\n", map->max_elem);
|
||||||
|
fprintf(stderr, " - Flags: %#x\n\n", map->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bpf_map_attach(const char *name, const struct bpf_elf_map *map,
|
static int bpf_map_attach(const char *name, const struct bpf_elf_map *map,
|
||||||
|
|
@ -1139,7 +1183,7 @@ static int bpf_map_attach(const char *name, const struct bpf_elf_map *map,
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
fd = bpf_map_create(map->type, map->size_key, map->size_value,
|
fd = bpf_map_create(map->type, map->size_key, map->size_value,
|
||||||
map->max_elem);
|
map->max_elem, map->flags);
|
||||||
if (fd < 0 || ctx->verbose) {
|
if (fd < 0 || ctx->verbose) {
|
||||||
bpf_map_report(fd, name, map, ctx);
|
bpf_map_report(fd, name, map, ctx);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
|
|
@ -1283,6 +1327,11 @@ static int bpf_fetch_strtab(struct bpf_elf_ctx *ctx, int section,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool bpf_has_map_data(const struct bpf_elf_ctx *ctx)
|
||||||
|
{
|
||||||
|
return ctx->sym_tab && ctx->str_tab && ctx->sec_maps;
|
||||||
|
}
|
||||||
|
|
||||||
static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx)
|
static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct bpf_elf_sec_data data;
|
struct bpf_elf_sec_data data;
|
||||||
|
|
@ -1306,13 +1355,13 @@ static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx)
|
||||||
!strcmp(data.sec_name, ".strtab"))
|
!strcmp(data.sec_name, ".strtab"))
|
||||||
ret = bpf_fetch_strtab(ctx, i, &data);
|
ret = bpf_fetch_strtab(ctx, i, &data);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error parsing section %d! Perhapscheck with readelf -a?\n",
|
fprintf(stderr, "Error parsing section %d! Perhaps check with readelf -a?\n",
|
||||||
i);
|
i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->sym_tab && ctx->str_tab && ctx->sec_maps) {
|
if (bpf_has_map_data(ctx)) {
|
||||||
ret = bpf_maps_attach_all(ctx);
|
ret = bpf_maps_attach_all(ctx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error loading maps into kernel!\n");
|
fprintf(stderr, "Error loading maps into kernel!\n");
|
||||||
|
|
@ -1348,7 +1397,7 @@ static int bpf_fetch_prog(struct bpf_elf_ctx *ctx, const char *section)
|
||||||
|
|
||||||
fd = bpf_prog_attach(section, &prog, ctx);
|
fd = bpf_prog_attach(section, &prog, ctx);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
ctx->sec_done[i] = true;
|
ctx->sec_done[i] = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1412,7 +1461,8 @@ static int bpf_apply_relo_data(struct bpf_elf_ctx *ctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section)
|
static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section,
|
||||||
|
bool *lderr)
|
||||||
{
|
{
|
||||||
struct bpf_elf_sec_data data_relo, data_insn;
|
struct bpf_elf_sec_data data_relo, data_insn;
|
||||||
struct bpf_elf_prog prog;
|
struct bpf_elf_prog prog;
|
||||||
|
|
@ -1442,8 +1492,10 @@ static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section)
|
||||||
prog.license = ctx->license;
|
prog.license = ctx->license;
|
||||||
|
|
||||||
fd = bpf_prog_attach(section, &prog, ctx);
|
fd = bpf_prog_attach(section, &prog, ctx);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
continue;
|
*lderr = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->sec_done[i] = true;
|
ctx->sec_done[i] = true;
|
||||||
ctx->sec_done[idx] = true;
|
ctx->sec_done[idx] = true;
|
||||||
|
|
@ -1455,11 +1507,12 @@ static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section)
|
||||||
|
|
||||||
static int bpf_fetch_prog_sec(struct bpf_elf_ctx *ctx, const char *section)
|
static int bpf_fetch_prog_sec(struct bpf_elf_ctx *ctx, const char *section)
|
||||||
{
|
{
|
||||||
|
bool lderr = false;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (ctx->sym_tab)
|
if (bpf_has_map_data(ctx))
|
||||||
ret = bpf_fetch_prog_relo(ctx, section);
|
ret = bpf_fetch_prog_relo(ctx, section, &lderr);
|
||||||
if (ret < 0)
|
if (ret < 0 && !lderr)
|
||||||
ret = bpf_fetch_prog(ctx, section);
|
ret = bpf_fetch_prog(ctx, section);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -1504,8 +1557,12 @@ static int bpf_fill_prog_arrays(struct bpf_elf_ctx *ctx)
|
||||||
|
|
||||||
ret = bpf_map_update(ctx->map_fds[idx], &key_id,
|
ret = bpf_map_update(ctx->map_fds[idx], &key_id,
|
||||||
&fd, BPF_ANY);
|
&fd, BPF_ANY);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
return -ENOENT;
|
if (errno == E2BIG)
|
||||||
|
fprintf(stderr, "Tail call key %u for map %u out of bounds?\n",
|
||||||
|
key_id, map_id);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->sec_done[i] = true;
|
ctx->sec_done[i] = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@ enum {
|
||||||
#define BPF_ENV_UDS "TC_BPF_UDS"
|
#define BPF_ENV_UDS "TC_BPF_UDS"
|
||||||
#define BPF_ENV_MNT "TC_BPF_MNT"
|
#define BPF_ENV_MNT "TC_BPF_MNT"
|
||||||
|
|
||||||
|
#ifndef BPF_MAX_LOG
|
||||||
|
# define BPF_MAX_LOG 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef BPF_FS_MAGIC
|
#ifndef BPF_FS_MAGIC
|
||||||
# define BPF_FS_MAGIC 0xcafe4a11
|
# define BPF_FS_MAGIC 0xcafe4a11
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue