Skip to content

Commit

Permalink
p4tc: Introduce subscription filters for table entries
Browse files Browse the repository at this point in the history
Introduce subscription filters, as of now only for table entries, but we
intend to include externs in the future. To subscribe to a specific
event with a filter, the user must specify it when running tc monitor.

For example, if the user wants to filter the table entry create commands
from a pipeline (ptables), a table (tname2) with entry key srcport ==
80, the user will issue the following command:

tc monitor command/create ptables/table/cb/tname2 \
filter key.ptables.cb.tname2.srcPort = 80

If one creates a table entry like the following:

tc p4 create ptables/table/cb/tname2 srcPort  80 dstPort  443

And they would see the following in tc monitor:

created pipeline:  ptables(id 22)
 table: cb/tname2(id 2)entry priority 64000[permissions -RUD-PS-R--X--]
    entry key
     srcPort id:1 size:16b type:bit16 exact fieldval  80
     dstPort id:2 size:16b type:bit16 exact fieldval  443
    created by entity: tc (id 2)
    create by pid: 448
    created by process: tc
    dynamic false

    tmpl created false

Co-developed-by: Victor Nogueira <[email protected]>
Signed-off-by: Victor Nogueira <[email protected]>
Co-developed-by: Pedro Tammela <[email protected]>
Signed-off-by: Pedro Tammela <[email protected]>
Signed-off-by: Jamal Hadi Salim <[email protected]>
  • Loading branch information
jhsmt authored and vbnogueira committed May 24, 2024
1 parent 5b58af9 commit 2b5b327
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 43 deletions.
57 changes: 56 additions & 1 deletion include/net/p4tc.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ struct p4tc_dump_ctx {
struct p4tc_filter *entry_filter;
};

struct p4tc_filter_data {
union {
struct {
u32 id;
struct p4tc_table_entry *entry;
} table;
};
int cmd;
u32 obj_id;
};

enum {
P4TC_FILTER_OBJ_UNSPEC,
P4TC_FILTER_OBJ_TMPL_PIPELINE,
Expand All @@ -82,6 +93,39 @@ enum {

#define P4TC_FILTER_OBJ_MAX (__P4TC_FILTER_OBJ_MAX - 1)

int
p4tc_nlmsg_filtered_notify(struct net *net, struct sk_buff *skb,
const u32 portid, gfp_t gfp_flags,
const bool echo, netlink_filter_fn filter,
void *filter_data);

static inline int p4tc_obj_to_filter_obj(const u32 p4tc_obj, bool runtime)
{
if (runtime) {
switch (p4tc_obj) {
case P4TC_OBJ_RUNTIME_TABLE:
return P4TC_FILTER_OBJ_RUNTIME_TABLE;
case P4TC_OBJ_RUNTIME_EXTERN:
return P4TC_FILTER_OBJ_RUNTIME_EXT;
default:
return -EINVAL;
}
} else {
switch (p4tc_obj) {
case P4TC_OBJ_PIPELINE:
return P4TC_FILTER_OBJ_TMPL_PIPELINE;
case P4TC_OBJ_ACT:
return P4TC_FILTER_OBJ_TMPL_ACT;
case P4TC_OBJ_TABLE:
return P4TC_FILTER_OBJ_TMPL_TABLE;
case P4TC_OBJ_EXT:
return P4TC_FILTER_OBJ_TMPL_EXT;
default:
return -EINVAL;
}
}
}

struct p4tc_template_common;

struct p4tc_path_nlattrs {
Expand Down Expand Up @@ -742,8 +786,12 @@ p4tc_tmpl_table_entry_cu(struct net *net, struct nlattr *arg,
struct p4tc_table *table,
struct netlink_ext_ack *extack);
int p4tc_tbl_entry_root(struct net *net, struct sk_buff *skb,
struct nlmsghdr *n, int cmd,
struct nlmsghdr *n, struct nlattr **tb,
struct netlink_ext_ack *extack);
int p4tc_tbl_entry_filter_sub(struct sk_buff *skb,
struct p4tc_path_nlattrs *nl_path_attrs,
struct nlattr *nla, u32 cmd,
struct netlink_ext_ack *extack);
int p4tc_tbl_entry_dumpit(struct net *net, struct sk_buff *skb,
struct netlink_callback *cb,
struct nlattr *arg, char *p_name);
Expand All @@ -759,7 +807,14 @@ p4tc_filter_build(struct p4tc_filter_context *ctx,
struct nlattr *nla, struct netlink_ext_ack *extack);
bool p4tc_filter_exec(struct p4tc_filter *filter,
struct p4tc_table_entry *entry);
int p4tc_filter_broadcast_cb(struct sock *dsk, struct sk_buff *skb,
void *data);
void p4tc_filter_destroy(struct p4tc_filter *filter);
void p4tc_filter_sock_table_init(void);
int p4tc_filter_subscribe(struct sk_buff *skb,
struct p4tc_filter_context *ctx,
struct nlattr *nla,
struct netlink_ext_ack *extack);

struct tcf_p4act *
p4a_runt_prealloc_get_next(struct p4tc_act *act);
Expand Down
2 changes: 1 addition & 1 deletion include/net/p4tc_ext_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int p4tc_ctl_extern_dump(struct sk_buff *skb, struct netlink_callback *cb,
void p4tc_ext_purge(struct idr *idr);
void p4tc_ext_inst_purge(struct p4tc_extern_inst *inst);

int p4tc_ctl_extern(struct sk_buff *skb, struct nlmsghdr *n, int cmd,
int p4tc_ctl_extern(struct sk_buff *skb, struct nlmsghdr *n, struct nlattr **tb,
struct netlink_ext_ack *extack);
struct p4tc_extern_param *
p4tc_ext_param_find_byanyattr(struct idr *params_idr,
Expand Down
12 changes: 12 additions & 0 deletions include/uapi/linux/p4tc.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,24 @@ enum {
#define p4tc_data_perm_rm_create(perm) \
(((perm) & ~P4TC_DATA_PERM_C))

/* Root attributes */
enum {
P4TC_SUBSCRIBE_UNSPEC,
P4TC_SUBSCRIBE_OBJNAME, /* object name */
P4TC_SUBSCRIBE_OBJID, /* object 32-bit ID */
__P4TC_SUBSCRIBE_MAX,
};

#define P4TC_SUBSCRIBE_MAX (__P4TC_SUBSCRIBE_MAX - 1)

/* Root attributes */
enum {
P4TC_ROOT_UNSPEC,
P4TC_ROOT, /* nested messages */
P4TC_ROOT_PNAME, /* string - mandatory for pipeline create */
P4TC_ROOT_COUNT,
P4TC_ROOT_FLAGS,
P4TC_ROOT_SUBSCRIBE, /* nested subscribe message, will contain filter */
__P4TC_ROOT_MAX,
};

Expand Down Expand Up @@ -141,6 +152,7 @@ enum {
P4TC_PATH,
P4TC_PARAMS,
P4TC_COUNT,
P4TC_CMD,
__P4TC_MAX,
};

Expand Down
2 changes: 2 additions & 0 deletions include/uapi/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,8 @@ enum rtnetlink_groups {
#define RTNLGRP_TUNNEL RTNLGRP_TUNNEL
RTNLGRP_STATS,
#define RTNLGRP_STATS RTNLGRP_STATS
RTNLGRP_P4TC,
#define RTNLGRP_P4TC RTNLGRP_P4TC
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
Expand Down
12 changes: 3 additions & 9 deletions net/sched/p4tc/p4tc_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -1984,28 +1984,22 @@ int p4tc_ctl_extern_dump(struct sk_buff *skb, struct netlink_callback *cb,
return skb->len;
}

int p4tc_ctl_extern(struct sk_buff *skb, struct nlmsghdr *n, int cmd,
int p4tc_ctl_extern(struct sk_buff *skb, struct nlmsghdr *n, struct nlattr **tb,
struct netlink_ext_ack *extack)
{
struct nlattr *tb[P4TC_ROOT_MAX + 1];
struct net *net = sock_net(skb->sk);
u32 portid = NETLINK_CB(skb).portid;
struct p4tc_pipeline *pipeline;
struct nlattr *root;
char *pname = NULL;
u32 flags = 0;
int ret = 0;

if (cmd != RTM_P4TC_GET && !netlink_capable(skb, CAP_NET_ADMIN)) {
if (n->nlmsg_type != RTM_P4TC_GET &&
!netlink_capable(skb, CAP_NET_ADMIN)) {
NL_SET_ERR_MSG(extack, "Need CAP_NET_ADMIN to do CUD ops");
return -EPERM;
}

ret = nlmsg_parse(n, sizeof(struct p4tcmsg), tb, P4TC_ROOT_MAX,
p4tc_root_policy, extack);
if (ret < 0)
return ret;

if (tb[P4TC_ROOT_PNAME])
pname = nla_data(tb[P4TC_ROOT_PNAME]);

Expand Down
Loading

0 comments on commit 2b5b327

Please sign in to comment.